diff --git a/.github/label-pr-config.yml b/.github/label-pr-config.yml index 3961cda0e38724..701d494ab40bd8 100644 --- a/.github/label-pr-config.yml +++ b/.github/label-pr-config.yml @@ -86,7 +86,7 @@ subSystemLabels: # Oddities first /^lib\/(?:punycode|\w+\/freelist|sys\.js)/: '' /^lib\/constants\.js$/: lib / src - /^lib\/internal/debugger$/: debugger + /^lib\/internal\/debugger$/: debugger /^lib\/internal\/linkedlist\.js$/: timers /^lib\/internal\/bootstrap/: lib / src /^lib\/internal\/v8_prof_/: tools diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml index 823bb4be4f0dbb..884ce035f1d392 100644 --- a/.github/workflows/auto-start-ci.yml +++ b/.github/workflows/auto-start-ci.yml @@ -45,7 +45,7 @@ jobs: if: needs.get-prs-for-ci.outputs.numbers != '' runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false diff --git a/.github/workflows/build-tarball.yml b/.github/workflows/build-tarball.yml index ff0a9d725d304a..156373cce41992 100644 --- a/.github/workflows/build-tarball.yml +++ b/.github/workflows/build-tarball.yml @@ -39,7 +39,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -57,7 +57,7 @@ jobs: mkdir tarballs mv *.tar.gz tarballs - name: Upload tarball artifact - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: tarballs path: tarballs @@ -65,7 +65,7 @@ jobs: needs: build-tarball runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -75,7 +75,7 @@ jobs: - name: Environment Information run: npx envinfo - name: Download tarball - uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: tarballs path: tarballs diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 48dd2a1fd902c8..29306cc4c3d5bf 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -38,7 +38,7 @@ jobs: fail-fast: false runs-on: ${{ matrix.windows }} steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/commit-lint.yml b/.github/workflows/commit-lint.yml index 6edd0980695e97..652dede5a1a86f 100644 --- a/.github/workflows/commit-lint.yml +++ b/.github/workflows/commit-lint.yml @@ -17,7 +17,7 @@ jobs: run: | echo "plusOne=$((${{ github.event.pull_request.commits }} + 1))" >> $GITHUB_OUTPUT echo "minusOne=$((${{ github.event.pull_request.commits }} - 1))" >> $GITHUB_OUTPUT - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: ${{ steps.nb-of-commits.outputs.plusOne }} persist-credentials: false diff --git a/.github/workflows/commit-queue.yml b/.github/workflows/commit-queue.yml index 7657a7790a94e1..e1c1edbeb961fa 100644 --- a/.github/workflows/commit-queue.yml +++ b/.github/workflows/commit-queue.yml @@ -58,7 +58,7 @@ jobs: if: needs.get_mergeable_prs.outputs.numbers != '' runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: # Needs the whole git history for ncu to work # See https://github.com/nodejs/node-core-utils/pull/486 diff --git a/.github/workflows/coverage-linux-without-intl.yml b/.github/workflows/coverage-linux-without-intl.yml index a2351225d6efbd..fcf2776f58166d 100644 --- a/.github/workflows/coverage-linux-without-intl.yml +++ b/.github/workflows/coverage-linux-without-intl.yml @@ -41,7 +41,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -68,7 +68,7 @@ jobs: - name: Clean tmp run: rm -rf coverage/tmp && rm -rf out - name: Upload - uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1 + uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # v4.3.1 with: directory: ./coverage token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/coverage-linux.yml b/.github/workflows/coverage-linux.yml index 10705fc16a749c..0c68c4d2048859 100644 --- a/.github/workflows/coverage-linux.yml +++ b/.github/workflows/coverage-linux.yml @@ -41,7 +41,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -68,7 +68,7 @@ jobs: - name: Clean tmp run: rm -rf coverage/tmp && rm -rf out - name: Upload - uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1 + uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # v4.3.1 with: directory: ./coverage token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/coverage-windows.yml b/.github/workflows/coverage-windows.yml index ead5743f51b39e..a9cca9bf7ded02 100644 --- a/.github/workflows/coverage-windows.yml +++ b/.github/workflows/coverage-windows.yml @@ -41,7 +41,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: windows-2022 steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -67,7 +67,7 @@ jobs: - name: Clean tmp run: npx rimraf ./coverage/tmp - name: Upload - uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1 + uses: codecov/codecov-action@5ecb98a3c6b747ed38dc09f787459979aebb39be # v4.3.1 with: directory: ./coverage token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/daily-wpt-fyi.yml b/.github/workflows/daily-wpt-fyi.yml index 62eb8b29f43ecc..2c9a98540299a1 100644 --- a/.github/workflows/daily-wpt-fyi.yml +++ b/.github/workflows/daily-wpt-fyi.yml @@ -57,7 +57,7 @@ jobs: SHORT_SHA=$(node -p 'process.version.split(/-nightly\d{8}/)[1]') echo "NIGHTLY_REF=$(gh api /repos/nodejs/node/commits/$SHORT_SHA --jq '.sha')" >> $GITHUB_ENV - name: Checkout ${{ steps.setup-node.outputs.node-version }} - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false ref: ${{ env.NIGHTLY_REF || steps.setup-node.outputs.node-version }} @@ -73,7 +73,7 @@ jobs: run: rm -rf wpt working-directory: test/fixtures - name: Checkout epochs/daily WPT - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: repository: web-platform-tests/wpt persist-credentials: false @@ -98,7 +98,7 @@ jobs: run: rm -rf deps/undici - name: Checkout undici if: ${{ env.WPT_REPORT != '' }} - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: repository: nodejs/undici persist-credentials: false @@ -121,7 +121,7 @@ jobs: run: cp wptreport.json wptreport-${{ steps.setup-node.outputs.node-version }}.json - name: Upload GitHub Actions artifact if: ${{ env.WPT_REPORT != '' }} - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: path: out/wpt/wptreport-*.json name: WPT Report for ${{ steps.setup-node.outputs.node-version }} diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index d5f458f5b31a35..e6d1be16315f99 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -17,7 +17,7 @@ jobs: # not working on gcc-8 and gcc-9 see https://github.com/nodejs/node/issues/38570 container: gcc:11 steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 5de7373a8baf35..a46a1d34fcf5c5 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -24,7 +24,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} @@ -35,7 +35,7 @@ jobs: run: npx envinfo - name: Build run: NODE=$(command -v node) make doc-only - - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: docs path: out/doc diff --git a/.github/workflows/find-inactive-collaborators.yml b/.github/workflows/find-inactive-collaborators.yml index 4b60ad4b40f9ee..8f22aebcd35839 100644 --- a/.github/workflows/find-inactive-collaborators.yml +++ b/.github/workflows/find-inactive-collaborators.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/find-inactive-tsc.yml b/.github/workflows/find-inactive-tsc.yml index b8ef8ef1f92d8a..aef37ae309d1b6 100644 --- a/.github/workflows/find-inactive-tsc.yml +++ b/.github/workflows/find-inactive-tsc.yml @@ -20,13 +20,13 @@ jobs: steps: - name: Checkout the repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: 0 persist-credentials: false - name: Clone nodejs/TSC repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: 0 path: .tmp diff --git a/.github/workflows/license-builder.yml b/.github/workflows/license-builder.yml index c1cbfafc1ac789..b68e8b2f0e6a46 100644 --- a/.github/workflows/license-builder.yml +++ b/.github/workflows/license-builder.yml @@ -17,7 +17,7 @@ jobs: if: github.repository == 'nodejs/node' runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - run: ./tools/license-builder.sh # Run the license builder tool diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index dd1f9ee1ae6533..cac39cbb53f649 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -25,7 +25,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} @@ -40,7 +40,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -55,7 +55,7 @@ jobs: if: ${{ github.event.pull_request && github.event.pull_request.draft == false && github.base_ref == github.event.repository.default_branch }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: 0 persist-credentials: false @@ -93,7 +93,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} @@ -118,7 +118,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -135,7 +135,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Use Python ${{ env.PYTHON_VERSION }} @@ -153,7 +153,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - run: shellcheck -V @@ -163,7 +163,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - uses: mszostok/codeowners-validator@7f3f5e28c6d7b8dfae5731e54ce2272ca384592f @@ -173,7 +173,7 @@ jobs: if: ${{ github.event.pull_request }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: 2 persist-credentials: false @@ -182,7 +182,7 @@ jobs: lint-readme: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - run: tools/lint-readme-lists.mjs diff --git a/.github/workflows/notify-on-push.yml b/.github/workflows/notify-on-push.yml index a7f63c7bcad9ea..858a1e43705468 100644 --- a/.github/workflows/notify-on-push.yml +++ b/.github/workflows/notify-on-push.yml @@ -34,7 +34,7 @@ jobs: permissions: pull-requests: write steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Check commit message diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index bee3bf155f7059..66e13d64895f7a 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,12 +33,12 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 + uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Checkout code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false @@ -65,7 +65,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: Upload artifact - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: SARIF file path: results.sarif @@ -73,6 +73,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: Upload to code-scanning - uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.24.9 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: results.sarif diff --git a/.github/workflows/test-asan.yml b/.github/workflows/test-asan.yml index 495f6679d950d5..bfb2da96c2ca80 100644 --- a/.github/workflows/test-asan.yml +++ b/.github/workflows/test-asan.yml @@ -46,7 +46,7 @@ jobs: LINK: clang++ CONFIG_FLAGS: --enable-asan steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/test-internet.yml b/.github/workflows/test-internet.yml index 2f50448d45aded..47f0774d04cc82 100644 --- a/.github/workflows/test-internet.yml +++ b/.github/workflows/test-internet.yml @@ -40,7 +40,7 @@ jobs: if: github.repository == 'nodejs/node' || github.event_name != 'schedule' runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index cebcf5d1152a5b..f7f0c0aa1d7cdf 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -34,7 +34,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/test-macos.yml b/.github/workflows/test-macos.yml index ddcda36bd71aa6..58389e97a53923 100644 --- a/.github/workflows/test-macos.yml +++ b/.github/workflows/test-macos.yml @@ -40,7 +40,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: macos-14 steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/test-ubsan.yml b/.github/workflows/test-ubsan.yml index ef88b76496dcfb..f180f3c08e4af7 100644 --- a/.github/workflows/test-ubsan.yml +++ b/.github/workflows/test-ubsan.yml @@ -45,7 +45,7 @@ jobs: LINK: g++ CONFIG_FLAGS: --enable-ubsan steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Store suppressions path diff --git a/.github/workflows/timezone-update.yml b/.github/workflows/timezone-update.yml index 00158082692fc6..d96d011984de95 100644 --- a/.github/workflows/timezone-update.yml +++ b/.github/workflows/timezone-update.yml @@ -20,12 +20,12 @@ jobs: steps: - name: Checkout nodejs/node - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Checkout unicode-org/icu-data - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: path: icu-data persist-credentials: false diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml index d333e1e0fda0bf..5e77678ab0c25c 100644 --- a/.github/workflows/tools.yml +++ b/.github/workflows/tools.yml @@ -297,7 +297,7 @@ jobs: tail -n1 temp-output | grep "NEW_VERSION=" >> "$GITHUB_ENV" || true rm temp-output steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 if: github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id with: persist-credentials: false diff --git a/.github/workflows/update-openssl.yml b/.github/workflows/update-openssl.yml index 23361dec160467..070bf37d24be25 100644 --- a/.github/workflows/update-openssl.yml +++ b/.github/workflows/update-openssl.yml @@ -14,7 +14,7 @@ jobs: if: github.repository == 'nodejs/node' runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Check and download new OpenSSL version diff --git a/.github/workflows/update-v8.yml b/.github/workflows/update-v8.yml index e2b58456bf789a..9d13e87ed505c6 100644 --- a/.github/workflows/update-v8.yml +++ b/.github/workflows/update-v8.yml @@ -16,7 +16,7 @@ jobs: if: github.repository == 'nodejs/node' runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: persist-credentials: false - name: Cache node modules and update-v8 diff --git a/.mailmap b/.mailmap index 1a3408a3f221d5..06fc5872ce3513 100644 --- a/.mailmap +++ b/.mailmap @@ -98,6 +98,7 @@ Chen Gang Chen Gang <13298548+MoonBall@users.noreply.github.com> Chengzhong Wu Chengzhong Wu +Chengzhong Wu Chew Choon Keat Chris Andrews Chris Johnson diff --git a/BUILDING.md b/BUILDING.md index ed40bd90e5630a..0cea36cab53527 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -546,11 +546,14 @@ If you encounter any difficulties, consider disabling `mold` as a troubleshooting step. If you plan to frequently rebuild Node.js, especially if using several -branches, installing `ccache` and `mold` can help to greatly reduce build +branches, installing `ccache` can help to greatly reduce build times. Set up with: On GNU/Linux: +Tips: `mold` can speed up the link process, which can't be cached, you may +need to install the latest version but not the apt version. + ```bash sudo apt install ccache mold # for Debian/Ubuntu, included in most Linux distros export CC="ccache gcc" # add to your .profile @@ -558,13 +561,17 @@ export CXX="ccache g++" # add to your .profile export LDFLAGS="-fuse-ld=mold" # add to your .profile ``` +Refs: + +1. +2. + On macOS: ```bash -brew install ccache mold # see https://brew.sh +brew install ccache # see https://brew.sh export CC="ccache cc" # add to ~/.zshrc or other shell config file export CXX="ccache c++" # add to ~/.zshrc or other shell config file -export LDFLAGS="-fuse-ld=mold" # add to ~/.zshrc or other shell config file ``` This will allow for near-instantaneous rebuilds when switching branches back @@ -582,11 +589,6 @@ the specified directory. The JS debugger of Visual Studio Code supports this configuration since the November 2020 version and allows for setting breakpoints. -Refs: - -1. -2. - #### Troubleshooting Unix and macOS builds Stale builds can sometimes result in `file not found` errors while building. diff --git a/CHANGELOG.md b/CHANGELOG.md index 45f135aeb94378..daca6ff0c6e392 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,7 +35,8 @@ release. -20.13.1
+20.14.0
+20.13.1
20.13.0
20.12.2
20.12.1
diff --git a/common.gypi b/common.gypi index c49e2494659bf2..0af8af37c6cf02 100644 --- a/common.gypi +++ b/common.gypi @@ -37,7 +37,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.20', + 'v8_embedder_string': '-node.23', ##### V8 defaults for Node.js ##### diff --git a/deps/corepack/CHANGELOG.md b/deps/corepack/CHANGELOG.md index f5cef27cc047f9..20d282c3a7b8e0 100644 --- a/deps/corepack/CHANGELOG.md +++ b/deps/corepack/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [0.28.1](https://github.com/nodejs/corepack/compare/v0.28.0...v0.28.1) (2024-05-10) + + +### Features + +* add support for `COREPACK_INTEGRITY_KEYS=0` ([#470](https://github.com/nodejs/corepack/issues/470)) ([f15ebc2](https://github.com/nodejs/corepack/commit/f15ebc289ebcd6a86580f15ae3c4ef0e1be37c4b)) +* update package manager versions ([#469](https://github.com/nodejs/corepack/issues/469)) ([985895b](https://github.com/nodejs/corepack/commit/985895bccb5ec68b3645c540d8500c572e1ccadb)) + + +### Bug Fixes + +* COREPACK_NPM_REGISTRY should allow for username/password auth ([#466](https://github.com/nodejs/corepack/issues/466)) ([6efa349](https://github.com/nodejs/corepack/commit/6efa34988229918debe6e881d45ba6715282f283)) + ## [0.28.0](https://github.com/nodejs/corepack/compare/v0.27.0...v0.28.0) (2024-04-20) diff --git a/deps/corepack/README.md b/deps/corepack/README.md index 42dc8c19085e88..f72f7f71ef77e8 100644 --- a/deps/corepack/README.md +++ b/deps/corepack/README.md @@ -296,8 +296,9 @@ same major line. Should you need to upgrade to a new major, use an explicit - `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY` are supported through [`node-proxy-agent`](https://github.com/TooTallNate/node-proxy-agent). -- `COREPACK_INTEGRITY_KEYS` can be set to an empty string to instruct Corepack - to skip integrity checks, or a JSON string containing custom keys. +- `COREPACK_INTEGRITY_KEYS` can be set to an empty string or `0` to + instruct Corepack to skip integrity checks, or to a JSON string containing + custom keys. ## Troubleshooting diff --git a/deps/corepack/dist/lib/corepack.cjs b/deps/corepack/dist/lib/corepack.cjs index f81b561ce54d87..e2a2cde7446d24 100644 --- a/deps/corepack/dist/lib/corepack.cjs +++ b/deps/corepack/dist/lib/corepack.cjs @@ -22417,7 +22417,7 @@ function String2(descriptor, ...args) { } // package.json -var version = "0.28.0"; +var version = "0.28.1"; // sources/Engine.ts var import_fs4 = __toESM(require("fs")); @@ -22429,7 +22429,7 @@ var import_semver4 = __toESM(require_semver2()); var config_default = { definitions: { npm: { - default: "10.5.2+sha1.0e9b72afaf5ecf8249b2abb4b7417db6739c1475", + default: "10.7.0+sha1.c87e0bbb7a53422670e423d0198120760f67c3b7", fetchLatestFrom: { type: "npm", package: "npm" @@ -22466,7 +22466,7 @@ var config_default = { } }, pnpm: { - default: "9.0.3+sha1.ff3ad37177cbd0843e533aab13d5e40a05803b47", + default: "9.1.0+sha1.217063ce3fcbf44f3051666f38b810f1ddefee4a", fetchLatestFrom: { type: "npm", package: "pnpm" @@ -22530,7 +22530,7 @@ var config_default = { package: "yarn" }, transparent: { - default: "4.1.1+sha224.00f08619463229f8ba40c4ee90e8c2e4ced1f11c3115c26f3b98432e", + default: "4.2.2+sha224.1e50daf19e5e249a025569752c60b88005fddf57d10fcde5fc68b88f", commands: [ [ "yarn", @@ -22702,7 +22702,7 @@ ${key.key} async function fetchLatestStableVersion(packageName) { const metadata = await fetchAsJson2(packageName, `latest`); const { version: version2, dist: { integrity, signatures } } = metadata; - if (process.env.COREPACK_INTEGRITY_KEYS !== ``) { + if (!shouldSkipIntegrityCheck()) { verifySignature({ packageName, version: version2, @@ -22736,8 +22736,8 @@ async function fetch(input, init) { if (typeof input === `string`) input = new URL(input); let headers = init?.headers; - const username = input.username ?? process.env.COREPACK_NPM_USERNAME; - const password = input.password ?? process.env.COREPACK_NPM_PASSWORD; + const username = input.username || process.env.COREPACK_NPM_USERNAME; + const password = input.password || process.env.COREPACK_NPM_PASSWORD; if (username || password) { headers = { ...headers, @@ -23031,7 +23031,7 @@ async function installVersion(installTarget, locator, { spec }) { } if (!build[1]) { const registry = getRegistryFromPackageManagerSpec(spec); - if (registry.type === `npm` && !registry.bin && process.env.COREPACK_INTEGRITY_KEYS !== ``) { + if (registry.type === `npm` && !registry.bin && !shouldSkipIntegrityCheck()) { if (signatures == null || integrity == null) ({ signatures, integrity } = await fetchTarballURLAndSignature(registry.package, version2)); verifySignature({ signatures, integrity, packageName: registry.package, version: version2 }); @@ -23136,6 +23136,9 @@ async function runVersion(locator, installSpec, binName, args) { process.mainModule = void 0; process.nextTick(import_module.default.runMain, binPath); } +function shouldSkipIntegrityCheck() { + return process.env.COREPACK_INTEGRITY_KEYS === `` || process.env.COREPACK_INTEGRITY_KEYS === `0`; +} // sources/semverUtils.ts var import_semver2 = __toESM(require_semver2()); diff --git a/deps/corepack/package.json b/deps/corepack/package.json index 5ca045e37041e0..3737c1920844d3 100644 --- a/deps/corepack/package.json +++ b/deps/corepack/package.json @@ -1,6 +1,6 @@ { "name": "corepack", - "version": "0.28.0", + "version": "0.28.1", "homepage": "https://github.com/nodejs/corepack#readme", "bugs": { "url": "https://github.com/nodejs/corepack/issues" diff --git a/deps/googletest/include/gtest/gtest-assertion-result.h b/deps/googletest/include/gtest/gtest-assertion-result.h index 56fe128f2a5aa7..74eb2b1f3c712c 100644 --- a/deps/googletest/include/gtest/gtest-assertion-result.h +++ b/deps/googletest/include/gtest/gtest-assertion-result.h @@ -129,7 +129,7 @@ namespace testing { // // Expected: Foo() is even // Actual: it's 5 -// + class GTEST_API_ AssertionResult { public: // Copy constructor. diff --git a/deps/googletest/include/gtest/gtest-param-test.h b/deps/googletest/include/gtest/gtest-param-test.h index 49a47ead03b79e..55ee088b93fb8d 100644 --- a/deps/googletest/include/gtest/gtest-param-test.h +++ b/deps/googletest/include/gtest/gtest-param-test.h @@ -178,7 +178,7 @@ TEST_P(DerivedTest, DoesBlah) { #include #include "gtest/internal/gtest-internal.h" -#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-param-util.h" // IWYU pragma: export #include "gtest/internal/gtest-port.h" namespace testing { @@ -469,7 +469,7 @@ internal::ParamConverterGenerator ConvertGenerator( ::testing::internal::CodeLocation(__FILE__, __LINE__)); \ return 0; \ } \ - static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int gtest_registering_dummy_; \ }; \ int GTEST_TEST_CLASS_NAME_(test_suite_name, \ test_name)::gtest_registering_dummy_ = \ @@ -514,8 +514,8 @@ internal::ParamConverterGenerator ConvertGenerator( ::testing::internal::DefaultParamName, \ DUMMY_PARAM_))))(info); \ } \ - static int gtest_##prefix##test_suite_name##_dummy_ \ - GTEST_ATTRIBUTE_UNUSED_ = \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int \ + gtest_##prefix##test_suite_name##_dummy_ = \ ::testing::UnitTest::GetInstance() \ ->parameterized_test_registry() \ .GetTestSuitePatternHolder( \ diff --git a/deps/googletest/include/gtest/gtest-typed-test.h b/deps/googletest/include/gtest/gtest-typed-test.h index 72de536bceec8e..305b0b50dd4cda 100644 --- a/deps/googletest/include/gtest/gtest-typed-test.h +++ b/deps/googletest/include/gtest/gtest-typed-test.h @@ -194,33 +194,34 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \ GTEST_NAME_GENERATOR_(CaseName) -#define TYPED_TEST(CaseName, TestName) \ - static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \ - "test-name must not be empty"); \ - template \ - class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ - : public CaseName { \ - private: \ - typedef CaseName TestFixture; \ - typedef gtest_TypeParam_ TypeParam; \ - void TestBody() override; \ - }; \ - static bool gtest_##CaseName##_##TestName##_registered_ \ - GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \ - CaseName, \ - ::testing::internal::TemplateSel, \ - GTEST_TYPE_PARAMS_( \ - CaseName)>::Register("", \ - ::testing::internal::CodeLocation( \ - __FILE__, __LINE__), \ - GTEST_STRINGIFY_(CaseName), \ - GTEST_STRINGIFY_(TestName), 0, \ - ::testing::internal::GenerateNames< \ - GTEST_NAME_GENERATOR_(CaseName), \ - GTEST_TYPE_PARAMS_(CaseName)>()); \ - template \ - void GTEST_TEST_CLASS_NAME_(CaseName, \ +#define TYPED_TEST(CaseName, TestName) \ + static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \ + "test-name must not be empty"); \ + template \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + void TestBody() override; \ + }; \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \ + gtest_##CaseName##_##TestName##_registered_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel, \ + GTEST_TYPE_PARAMS_( \ + CaseName)>::Register("", \ + ::testing::internal::CodeLocation( \ + __FILE__, __LINE__), \ + GTEST_STRINGIFY_(CaseName), \ + GTEST_STRINGIFY_(TestName), 0, \ + ::testing::internal::GenerateNames< \ + GTEST_NAME_GENERATOR_(CaseName), \ + GTEST_TYPE_PARAMS_(CaseName)>()); \ + template \ + void GTEST_TEST_CLASS_NAME_(CaseName, \ TestName)::TestBody() // Legacy API is deprecated but still available @@ -267,22 +268,23 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); TYPED_TEST_SUITE_P #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -#define TYPED_TEST_P(SuiteName, TestName) \ - namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ - template \ - class TestName : public SuiteName { \ - private: \ - typedef SuiteName TestFixture; \ - typedef gtest_TypeParam_ TypeParam; \ - void TestBody() override; \ - }; \ - static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ - GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \ - __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \ - GTEST_STRINGIFY_(TestName)); \ - } \ - template \ - void GTEST_SUITE_NAMESPACE_( \ +#define TYPED_TEST_P(SuiteName, TestName) \ + namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ + template \ + class TestName : public SuiteName { \ + private: \ + typedef SuiteName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + void TestBody() override; \ + }; \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \ + gtest_##TestName##_defined_ = \ + GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \ + __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \ + GTEST_STRINGIFY_(TestName)); \ + } \ + template \ + void GTEST_SUITE_NAMESPACE_( \ SuiteName)::TestName::TestBody() // Note: this won't work correctly if the trailing arguments are macros. @@ -290,8 +292,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \ } \ - static const char* const GTEST_REGISTERED_TEST_NAMES_( \ - SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static const char* const \ + GTEST_REGISTERED_TEST_NAMES_(SuiteName) = \ GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \ GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__) @@ -303,22 +305,24 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); REGISTER_TYPED_TEST_SUITE_P #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \ - static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \ - "test-suit-prefix must not be empty"); \ - static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \ - ::testing::internal::TypeParameterizedTestSuite< \ - SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \ - ::testing::internal::GenerateTypeList::type>:: \ - Register(GTEST_STRINGIFY_(Prefix), \ - ::testing::internal::CodeLocation(__FILE__, __LINE__), \ - >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \ - GTEST_STRINGIFY_(SuiteName), \ - GTEST_REGISTERED_TEST_NAMES_(SuiteName), \ - ::testing::internal::GenerateNames< \ - ::testing::internal::NameGeneratorSelector< \ - __VA_ARGS__>::type, \ - ::testing::internal::GenerateTypeList::type>()) +#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \ + static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \ + "test-suit-prefix must not be empty"); \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \ + gtest_##Prefix##_##SuiteName = \ + ::testing::internal::TypeParameterizedTestSuite< \ + SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \ + ::testing::internal::GenerateTypeList::type>:: \ + Register( \ + GTEST_STRINGIFY_(Prefix), \ + ::testing::internal::CodeLocation(__FILE__, __LINE__), \ + >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \ + GTEST_STRINGIFY_(SuiteName), \ + GTEST_REGISTERED_TEST_NAMES_(SuiteName), \ + ::testing::internal::GenerateNames< \ + ::testing::internal::NameGeneratorSelector< \ + __VA_ARGS__>::type, \ + ::testing::internal::GenerateTypeList::type>()) // Legacy API is deprecated but still available #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ diff --git a/deps/googletest/include/gtest/gtest.h b/deps/googletest/include/gtest/gtest.h index 45400fd0b2ccd7..c8996695203357 100644 --- a/deps/googletest/include/gtest/gtest.h +++ b/deps/googletest/include/gtest/gtest.h @@ -60,16 +60,16 @@ #include #include -#include "gtest/gtest-assertion-result.h" -#include "gtest/gtest-death-test.h" -#include "gtest/gtest-matchers.h" -#include "gtest/gtest-message.h" -#include "gtest/gtest-param-test.h" -#include "gtest/gtest-printers.h" -#include "gtest/gtest-test-part.h" -#include "gtest/gtest-typed-test.h" -#include "gtest/gtest_pred_impl.h" -#include "gtest/gtest_prod.h" +#include "gtest/gtest-assertion-result.h" // IWYU pragma: export +#include "gtest/gtest-death-test.h" // IWYU pragma: export +#include "gtest/gtest-matchers.h" // IWYU pragma: export +#include "gtest/gtest-message.h" // IWYU pragma: export +#include "gtest/gtest-param-test.h" // IWYU pragma: export +#include "gtest/gtest-printers.h" // IWYU pragma: export +#include "gtest/gtest-test-part.h" // IWYU pragma: export +#include "gtest/gtest-typed-test.h" // IWYU pragma: export +#include "gtest/gtest_pred_impl.h" // IWYU pragma: export +#include "gtest/gtest_prod.h" // IWYU pragma: export #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" @@ -607,7 +607,7 @@ class GTEST_API_ TestInfo { friend class internal::UnitTestImpl; friend class internal::StreamingListenerTest; friend TestInfo* internal::MakeAndRegisterTestInfo( - const char* test_suite_name, const char* name, const char* type_param, + std::string test_suite_name, const char* name, const char* type_param, const char* value_param, internal::CodeLocation code_location, internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc, internal::TearDownTestSuiteFunc tear_down_tc, @@ -615,7 +615,7 @@ class GTEST_API_ TestInfo { // Constructs a TestInfo object. The newly constructed instance assumes // ownership of the factory object. - TestInfo(const std::string& test_suite_name, const std::string& name, + TestInfo(std::string test_suite_name, std::string name, const char* a_type_param, // NULL if not a type-parameterized test const char* a_value_param, // NULL if not a value-parameterized test internal::CodeLocation a_code_location, @@ -683,7 +683,7 @@ class GTEST_API_ TestSuite { // this is not a type-parameterized test. // set_up_tc: pointer to the function that sets up the test suite // tear_down_tc: pointer to the function that tears down the test suite - TestSuite(const char* name, const char* a_type_param, + TestSuite(const std::string& name, const char* a_type_param, internal::SetUpTestSuiteFunc set_up_tc, internal::TearDownTestSuiteFunc tear_down_tc); @@ -1262,6 +1262,20 @@ class GTEST_API_ UnitTest { // total_test_suite_count() - 1. If i is not in that range, returns NULL. TestSuite* GetMutableTestSuite(int i); + // Invokes OsStackTrackGetterInterface::UponLeavingGTest. UponLeavingGTest() + // should be called immediately before Google Test calls user code. It saves + // some information about the current stack that CurrentStackTrace() will use + // to find and hide Google Test stack frames. + void UponLeavingGTest(); + + // Sets the TestSuite object for the test that's currently running. + void set_current_test_suite(TestSuite* a_current_test_suite) + GTEST_LOCK_EXCLUDED_(mutex_); + + // Sets the TestInfo object for the test that's currently running. + void set_current_test_info(TestInfo* a_current_test_info) + GTEST_LOCK_EXCLUDED_(mutex_); + // Accessors for the implementation object. internal::UnitTestImpl* impl() { return impl_; } const internal::UnitTestImpl* impl() const { return impl_; } @@ -1270,6 +1284,8 @@ class GTEST_API_ UnitTest { // members of UnitTest. friend class ScopedTrace; friend class Test; + friend class TestInfo; + friend class TestSuite; friend class internal::AssertHelper; friend class internal::StreamingListenerTest; friend class internal::UnitTestRecordPropertyTestHelper; @@ -2308,7 +2324,8 @@ TestInfo* RegisterTest(const char* test_suite_name, const char* test_name, // tests are successful, or 1 otherwise. // // RUN_ALL_TESTS() should be invoked after the command line has been -// parsed by InitGoogleTest(). +// parsed by InitGoogleTest(). RUN_ALL_TESTS will tear down and delete any +// installed environments and should only be called once per binary. // // This function was formerly a macro; thus, it is in the global // namespace and has an all-caps name. diff --git a/deps/googletest/include/gtest/internal/gtest-death-test-internal.h b/deps/googletest/include/gtest/internal/gtest-death-test-internal.h index 61536d6572d36c..3925e36baf12f5 100644 --- a/deps/googletest/include/gtest/internal/gtest-death-test-internal.h +++ b/deps/googletest/include/gtest/internal/gtest-death-test-internal.h @@ -71,7 +71,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ // // exit status: The integer exit information in the format specified // by wait(2) -// exit code: The integer code passed to exit(3), _exit(2), or +// exit code: The integer code passed to exit(3), _Exit(2), or // returned from main() class GTEST_API_ DeathTest { public: diff --git a/deps/googletest/include/gtest/internal/gtest-filepath.h b/deps/googletest/include/gtest/internal/gtest-filepath.h index 5189c81dabfa66..6dc47be54ad3e7 100644 --- a/deps/googletest/include/gtest/internal/gtest-filepath.h +++ b/deps/googletest/include/gtest/internal/gtest-filepath.h @@ -43,6 +43,7 @@ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #include +#include #include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-string.h" @@ -70,8 +71,9 @@ class GTEST_API_ FilePath { public: FilePath() : pathname_("") {} FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {} + FilePath(FilePath&& rhs) noexcept : pathname_(std::move(rhs.pathname_)) {} - explicit FilePath(const std::string& pathname) : pathname_(pathname) { + explicit FilePath(std::string pathname) : pathname_(std::move(pathname)) { Normalize(); } @@ -79,6 +81,10 @@ class GTEST_API_ FilePath { Set(rhs); return *this; } + FilePath& operator=(FilePath&& rhs) noexcept { + pathname_ = std::move(rhs.pathname_); + return *this; + } void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; } diff --git a/deps/googletest/include/gtest/internal/gtest-internal.h b/deps/googletest/include/gtest/internal/gtest-internal.h index 806b08624cb45a..7e55dc605cb996 100644 --- a/deps/googletest/include/gtest/internal/gtest-internal.h +++ b/deps/googletest/include/gtest/internal/gtest-internal.h @@ -474,8 +474,8 @@ using SetUpTestSuiteFunc = void (*)(); using TearDownTestSuiteFunc = void (*)(); struct CodeLocation { - CodeLocation(const std::string& a_file, int a_line) - : file(a_file), line(a_line) {} + CodeLocation(std::string a_file, int a_line) + : file(std::move(a_file)), line(a_line) {} std::string file; int line; @@ -564,7 +564,7 @@ struct SuiteApiResolver : T { // The newly created TestInfo instance will assume // ownership of the factory object. GTEST_API_ TestInfo* MakeAndRegisterTestInfo( - const char* test_suite_name, const char* name, const char* type_param, + std::string test_suite_name, const char* name, const char* type_param, const char* value_param, CodeLocation code_location, TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc, TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory); @@ -595,8 +595,7 @@ class GTEST_API_ TypedTestSuitePState { fflush(stderr); posix::Abort(); } - registered_tests_.insert( - ::std::make_pair(test_name, CodeLocation(file, line))); + registered_tests_.emplace(test_name, CodeLocation(file, line)); return true; } @@ -700,7 +699,7 @@ class TypeParameterizedTest { // specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite, // Types). Valid values for 'index' are [0, N - 1] where N is the // length of Types. - static bool Register(const char* prefix, const CodeLocation& code_location, + static bool Register(const char* prefix, CodeLocation code_location, const char* case_name, const char* test_names, int index, const std::vector& type_names = GenerateNames()) { @@ -712,8 +711,7 @@ class TypeParameterizedTest { // list. MakeAndRegisterTestInfo( (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + - "/" + type_names[static_cast(index)]) - .c_str(), + "/" + type_names[static_cast(index)]), StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(), GetTypeName().c_str(), nullptr, // No value parameter. @@ -725,13 +723,9 @@ class TypeParameterizedTest { new TestFactoryImpl); // Next, recurses (at compile time) with the tail of the type list. - return TypeParameterizedTest::Register(prefix, - code_location, - case_name, - test_names, - index + 1, - type_names); + return TypeParameterizedTest:: + Register(prefix, std::move(code_location), case_name, test_names, + index + 1, type_names); } }; @@ -739,7 +733,7 @@ class TypeParameterizedTest { template class TypeParameterizedTest { public: - static bool Register(const char* /*prefix*/, const CodeLocation&, + static bool Register(const char* /*prefix*/, CodeLocation, const char* /*case_name*/, const char* /*test_names*/, int /*index*/, const std::vector& = @@ -786,7 +780,8 @@ class TypeParameterizedTestSuite { // Next, recurses (at compile time) with the tail of the test list. return TypeParameterizedTestSuite::Register(prefix, code_location, + Types>::Register(prefix, + std::move(code_location), state, case_name, SkipComma(test_names), type_names); @@ -1142,40 +1137,6 @@ class NativeArray { void (NativeArray::*clone_)(const Element*, size_t); }; -// Backport of std::index_sequence. -template -struct IndexSequence { - using type = IndexSequence; -}; - -// Double the IndexSequence, and one if plus_one is true. -template -struct DoubleSequence; -template -struct DoubleSequence, sizeofT> { - using type = IndexSequence; -}; -template -struct DoubleSequence, sizeofT> { - using type = IndexSequence; -}; - -// Backport of std::make_index_sequence. -// It uses O(ln(N)) instantiation depth. -template -struct MakeIndexSequenceImpl - : DoubleSequence::type, - N / 2>::type {}; - -template <> -struct MakeIndexSequenceImpl<0> : IndexSequence<> {}; - -template -using MakeIndexSequence = typename MakeIndexSequenceImpl::type; - -template -using IndexSequenceFor = typename MakeIndexSequence::type; - template struct Ignore { Ignore(...); // NOLINT @@ -1184,7 +1145,7 @@ struct Ignore { template struct ElemFromListImpl; template -struct ElemFromListImpl> { +struct ElemFromListImpl> { // We make Ignore a template to solve a problem with MSVC. // A non-template Ignore would work fine with `decltype(Ignore(I))...`, but // MSVC doesn't understand how to deal with that pack expansion. @@ -1195,9 +1156,8 @@ struct ElemFromListImpl> { template struct ElemFromList { - using type = - decltype(ElemFromListImpl::type>::Apply( - static_cast(nullptr)...)); + using type = decltype(ElemFromListImpl>::Apply( + static_cast(nullptr)...)); }; struct FlatTupleConstructTag {}; @@ -1222,9 +1182,9 @@ template struct FlatTupleBase; template -struct FlatTupleBase, IndexSequence> +struct FlatTupleBase, std::index_sequence> : FlatTupleElemBase, Idx>... { - using Indices = IndexSequence; + using Indices = std::index_sequence; FlatTupleBase() = default; template explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args) @@ -1259,14 +1219,15 @@ struct FlatTupleBase, IndexSequence> // implementations. // FlatTuple and ElemFromList are not recursive and have a fixed depth // regardless of T... -// MakeIndexSequence, on the other hand, it is recursive but with an +// std::make_index_sequence, on the other hand, it is recursive but with an // instantiation depth of O(ln(N)). template class FlatTuple : private FlatTupleBase, - typename MakeIndexSequence::type> { - using Indices = typename FlatTupleBase< - FlatTuple, typename MakeIndexSequence::type>::Indices; + std::make_index_sequence> { + using Indices = + typename FlatTupleBase, + std::make_index_sequence>::Indices; public: FlatTuple() = default; @@ -1540,7 +1501,8 @@ class NeverThrown { \ private: \ void TestBody() override; \ - static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \ + GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static ::testing::TestInfo* const \ + test_info_; \ }; \ \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \ diff --git a/deps/googletest/include/gtest/internal/gtest-param-util.h b/deps/googletest/include/gtest/internal/gtest-param-util.h index b04f7020636083..cc7ea531738c9d 100644 --- a/deps/googletest/include/gtest/internal/gtest-param-util.h +++ b/deps/googletest/include/gtest/internal/gtest-param-util.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -85,7 +86,7 @@ namespace internal { // TEST_P macro is used to define two tests with the same name // but in different namespaces. GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name, - CodeLocation code_location); + const CodeLocation& code_location); template class ParamGeneratorInterface; @@ -379,9 +380,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { // integer test parameter index. template std::string DefaultParamName(const TestParamInfo& info) { - Message name_stream; - name_stream << info.index; - return name_stream.GetString(); + return std::to_string(info.index); } template @@ -513,9 +512,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { typedef ParamGenerator(GeneratorCreationFunc)(); using ParamNameGeneratorFunc = std::string(const TestParamInfo&); - explicit ParameterizedTestSuiteInfo(const char* name, + explicit ParameterizedTestSuiteInfo(std::string name, CodeLocation code_location) - : test_suite_name_(name), code_location_(code_location) {} + : test_suite_name_(std::move(name)), + code_location_(std::move(code_location)) {} // Test suite base name for display purposes. const std::string& GetTestSuiteName() const override { @@ -529,20 +529,21 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { // prefix). test_base_name is the name of an individual test without // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is // test suite base name and DoBar is test base name. - void AddTestPattern(const char* test_suite_name, const char* test_base_name, + void AddTestPattern(const char*, + const char* test_base_name, TestMetaFactoryBase* meta_factory, CodeLocation code_location) { - tests_.push_back(std::shared_ptr(new TestInfo( - test_suite_name, test_base_name, meta_factory, code_location))); + tests_.emplace_back( + new TestInfo(test_base_name, meta_factory, std::move(code_location))); } // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information // about a generator. - int AddTestSuiteInstantiation(const std::string& instantiation_name, + int AddTestSuiteInstantiation(std::string instantiation_name, GeneratorCreationFunc* func, ParamNameGeneratorFunc* name_func, const char* file, int line) { - instantiations_.push_back( - InstantiationInfo(instantiation_name, func, name_func, file, line)); + instantiations_.emplace_back(std::move(instantiation_name), func, name_func, + file, line); return 0; // Return value used only to run this method in namespace scope. } // UnitTest class invokes this method to register tests in this test suite @@ -553,34 +554,31 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { void RegisterTests() override { bool generated_instantiations = false; - for (typename TestInfoContainer::iterator test_it = tests_.begin(); - test_it != tests_.end(); ++test_it) { - std::shared_ptr test_info = *test_it; - for (typename InstantiationContainer::iterator gen_it = - instantiations_.begin(); - gen_it != instantiations_.end(); ++gen_it) { - const std::string& instantiation_name = gen_it->name; - ParamGenerator generator((*gen_it->generator)()); - ParamNameGeneratorFunc* name_func = gen_it->name_func; - const char* file = gen_it->file; - int line = gen_it->line; - - std::string test_suite_name; + std::string test_suite_name; + std::string test_name; + for (const std::shared_ptr& test_info : tests_) { + for (const InstantiationInfo& instantiation : instantiations_) { + const std::string& instantiation_name = instantiation.name; + ParamGenerator generator((*instantiation.generator)()); + ParamNameGeneratorFunc* name_func = instantiation.name_func; + const char* file = instantiation.file; + int line = instantiation.line; + if (!instantiation_name.empty()) test_suite_name = instantiation_name + "/"; - test_suite_name += test_info->test_suite_base_name; + else + test_suite_name.clear(); + test_suite_name += test_suite_name_; size_t i = 0; std::set test_param_names; - for (typename ParamGenerator::iterator param_it = - generator.begin(); - param_it != generator.end(); ++param_it, ++i) { + for (const auto& param : generator) { generated_instantiations = true; - Message test_name_stream; + test_name.clear(); std::string param_name = - name_func(TestParamInfo(*param_it, i)); + name_func(TestParamInfo(param, i)); GTEST_CHECK_(IsValidParamName(param_name)) << "Parameterized test name '" << param_name @@ -592,23 +590,25 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { << "Duplicate parameterized test name '" << param_name << "', in " << file << " line " << line << std::endl; - test_param_names.insert(param_name); - if (!test_info->test_base_name.empty()) { - test_name_stream << test_info->test_base_name << "/"; + test_name.append(test_info->test_base_name).append("/"); } - test_name_stream << param_name; + test_name += param_name; + + test_param_names.insert(std::move(param_name)); + MakeAndRegisterTestInfo( - test_suite_name.c_str(), test_name_stream.GetString().c_str(), + test_suite_name, test_name.c_str(), nullptr, // No type parameter. - PrintToString(*param_it).c_str(), test_info->code_location, + PrintToString(param).c_str(), test_info->code_location, GetTestSuiteTypeId(), SuiteApiResolver::GetSetUpCaseOrSuite(file, line), SuiteApiResolver::GetTearDownCaseOrSuite(file, line), - test_info->test_meta_factory->CreateTestFactory(*param_it)); - } // for param_it - } // for gen_it - } // for test_it + test_info->test_meta_factory->CreateTestFactory(param)); + ++i; + } // for param + } // for instantiation + } // for test_info if (!generated_instantiations) { // There are no generaotrs, or they all generate nothing ... @@ -621,15 +621,13 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { // LocalTestInfo structure keeps information about a single test registered // with TEST_P macro. struct TestInfo { - TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name, + TestInfo(const char* a_test_base_name, TestMetaFactoryBase* a_test_meta_factory, CodeLocation a_code_location) - : test_suite_base_name(a_test_suite_base_name), - test_base_name(a_test_base_name), + : test_base_name(a_test_base_name), test_meta_factory(a_test_meta_factory), - code_location(a_code_location) {} + code_location(std::move(a_code_location)) {} - const std::string test_suite_base_name; const std::string test_base_name; const std::unique_ptr> test_meta_factory; const CodeLocation code_location; @@ -639,11 +637,10 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { // struct InstantiationInfo { - InstantiationInfo(const std::string& name_in, - GeneratorCreationFunc* generator_in, + InstantiationInfo(std::string name_in, GeneratorCreationFunc* generator_in, ParamNameGeneratorFunc* name_func_in, const char* file_in, int line_in) - : name(name_in), + : name(std::move(name_in)), generator(generator_in), name_func(name_func_in), file(file_in), @@ -704,29 +701,32 @@ class ParameterizedTestSuiteRegistry { // tests and instantiations of a particular test suite. template ParameterizedTestSuiteInfo* GetTestSuitePatternHolder( - const char* test_suite_name, CodeLocation code_location) { + std::string test_suite_name, CodeLocation code_location) { ParameterizedTestSuiteInfo* typed_test_info = nullptr; - for (auto& test_suite_info : test_suite_infos_) { - if (test_suite_info->GetTestSuiteName() == test_suite_name) { - if (test_suite_info->GetTestSuiteTypeId() != GetTypeId()) { - // Complain about incorrect usage of Google Test facilities - // and terminate the program since we cannot guaranty correct - // test suite setup and tear-down in this case. - ReportInvalidTestSuiteType(test_suite_name, code_location); - posix::Abort(); - } else { - // At this point we are sure that the object we found is of the same - // type we are looking for, so we downcast it to that type - // without further checks. - typed_test_info = CheckedDowncastToActualType< - ParameterizedTestSuiteInfo>(test_suite_info); - } - break; + + auto item_it = suite_name_to_info_index_.find(test_suite_name); + if (item_it != suite_name_to_info_index_.end()) { + auto* test_suite_info = test_suite_infos_[item_it->second]; + if (test_suite_info->GetTestSuiteTypeId() != GetTypeId()) { + // Complain about incorrect usage of Google Test facilities + // and terminate the program since we cannot guaranty correct + // test suite setup and tear-down in this case. + ReportInvalidTestSuiteType(test_suite_name.c_str(), code_location); + posix::Abort(); + } else { + // At this point we are sure that the object we found is of the same + // type we are looking for, so we downcast it to that type + // without further checks. + typed_test_info = + CheckedDowncastToActualType>( + test_suite_info); } } if (typed_test_info == nullptr) { typed_test_info = new ParameterizedTestSuiteInfo( - test_suite_name, code_location); + test_suite_name, std::move(code_location)); + suite_name_to_info_index_.emplace(std::move(test_suite_name), + test_suite_infos_.size()); test_suite_infos_.push_back(typed_test_info); } return typed_test_info; @@ -740,8 +740,9 @@ class ParameterizedTestSuiteRegistry { #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ template ParameterizedTestCaseInfo* GetTestCasePatternHolder( - const char* test_case_name, CodeLocation code_location) { - return GetTestSuitePatternHolder(test_case_name, code_location); + std::string test_case_name, CodeLocation code_location) { + return GetTestSuitePatternHolder(std::move(test_case_name), + std::move(code_location)); } #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ @@ -750,6 +751,7 @@ class ParameterizedTestSuiteRegistry { using TestSuiteInfoContainer = ::std::vector; TestSuiteInfoContainer test_suite_infos_; + ::std::unordered_map suite_name_to_info_index_; ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) = delete; @@ -776,7 +778,7 @@ class TypeParameterizedTestSuiteRegistry { private: struct TypeParameterizedTestSuiteInfo { explicit TypeParameterizedTestSuiteInfo(CodeLocation c) - : code_location(c), instantiated(false) {} + : code_location(std::move(c)), instantiated(false) {} CodeLocation code_location; bool instantiated; @@ -805,12 +807,12 @@ class ValueArray { template operator ParamGenerator() const { // NOLINT - return ValuesIn(MakeVector(MakeIndexSequence())); + return ValuesIn(MakeVector(std::make_index_sequence())); } private: template - std::vector MakeVector(IndexSequence) const { + std::vector MakeVector(std::index_sequence) const { return std::vector{static_cast(v_.template Get())...}; } @@ -840,7 +842,7 @@ class CartesianProductGenerator template class IteratorImpl; template - class IteratorImpl> + class IteratorImpl> : public ParamIteratorInterface { public: IteratorImpl(const ParamGeneratorInterface* base, @@ -931,7 +933,7 @@ class CartesianProductGenerator std::shared_ptr current_value_; }; - using Iterator = IteratorImpl::type>; + using Iterator = IteratorImpl>; std::tuple...> generators_; }; diff --git a/deps/googletest/include/gtest/internal/gtest-port-arch.h b/deps/googletest/include/gtest/internal/gtest-port-arch.h index 3162f2b1cbd229..7ec968f312e4f4 100644 --- a/deps/googletest/include/gtest/internal/gtest-port-arch.h +++ b/deps/googletest/include/gtest/internal/gtest-port-arch.h @@ -56,6 +56,8 @@ #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE) #define GTEST_OS_WINDOWS_PHONE 1 #define GTEST_OS_WINDOWS_TV_TITLE 1 +#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES) +#define GTEST_OS_WINDOWS_GAMES 1 #else // WINAPI_FAMILY defined but no known partition matched. // Default to desktop. diff --git a/deps/googletest/include/gtest/internal/gtest-port.h b/deps/googletest/include/gtest/internal/gtest-port.h index fa457b7880e011..8d27c2c4f72f94 100644 --- a/deps/googletest/include/gtest/internal/gtest-port.h +++ b/deps/googletest/include/gtest/internal/gtest-port.h @@ -194,8 +194,6 @@ // // Macros for basic C++ coding: // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. -// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a -// variable don't have to be used. // GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. // GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is // suppressed (constant conditional). @@ -340,8 +338,8 @@ #if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS) #define GTEST_INTERNAL_HAS_ABSL_FLAGS // Used only in this file. -#include "absl/flags/flag.h" #include "absl/flags/declare.h" +#include "absl/flags/flag.h" #include "absl/flags/reflection.h" #endif @@ -609,7 +607,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; defined(GTEST_OS_NETBSD) || defined(GTEST_OS_FUCHSIA) || \ defined(GTEST_OS_DRAGONFLY) || defined(GTEST_OS_GNU_KFREEBSD) || \ defined(GTEST_OS_OPENBSD) || defined(GTEST_OS_HAIKU) || \ - defined(GTEST_OS_GNU_HURD)) + defined(GTEST_OS_GNU_HURD) || defined(GTEST_OS_SOLARIS) || \ + defined(GTEST_OS_AIX) || defined(GTEST_OS_ZOS)) #define GTEST_HAS_PTHREAD 1 #else #define GTEST_HAS_PTHREAD 0 @@ -659,9 +658,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // platforms except known mobile / embedded ones. Also, if the port doesn't have // a file system, stream redirection is not supported. #if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \ - defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_ESP8266) || \ - defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) || \ - !GTEST_HAS_FILE_SYSTEM + defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_WINDOWS_GAMES) || \ + defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \ + defined(GTEST_OS_QURT) || !GTEST_HAS_FILE_SYSTEM #define GTEST_HAS_STREAM_REDIRECTION 0 #else #define GTEST_HAS_STREAM_REDIRECTION 1 @@ -671,7 +670,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // Determines whether to support death tests. // pops up a dialog window that cannot be suppressed programmatically. #if (defined(GTEST_OS_LINUX) || defined(GTEST_OS_CYGWIN) || \ - defined(GTEST_OS_SOLARIS) || \ + defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_ZOS) || \ (defined(GTEST_OS_MAC) && !defined(GTEST_OS_IOS)) || \ (defined(GTEST_OS_WINDOWS_DESKTOP) && _MSC_VER) || \ defined(GTEST_OS_WINDOWS_MINGW) || defined(GTEST_OS_AIX) || \ @@ -749,6 +748,20 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #define GTEST_HAVE_ATTRIBUTE_(x) 0 #endif +// GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE +// +// A function-like feature checking macro that accepts C++11 style attributes. +// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6 +// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't +// find `__has_cpp_attribute`, will evaluate to 0. +#if defined(__has_cpp_attribute) +// NOTE: requiring __cplusplus above should not be necessary, but +// works around https://bugs.llvm.org/show_bug.cgi?id=23435. +#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) 0 +#endif + // GTEST_HAVE_FEATURE_ // // A function-like feature checking macro that is a wrapper around @@ -760,14 +773,22 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #endif // Use this annotation after a variable or parameter declaration to tell the -// compiler the variable/parameter does not have to be used. +// compiler the variable/parameter may be used. // Example: // -// GTEST_ATTRIBUTE_UNUSED_ int foo = bar(); -#if GTEST_HAVE_ATTRIBUTE_(unused) -#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused)) +// GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED int foo = bar(); +// +// This can be removed once we only support only C++17 or newer and +// [[maybe_unused]] is available on all supported platforms. +#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(maybe_unused) +#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]] +#elif GTEST_HAVE_ATTRIBUTE_(unused) +// This is inferior to [[maybe_unused]] as it can produce a +// -Wused-but-marked-unused warning on optionally used symbols, but it is all we +// have. +#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED __attribute__((__unused__)) #else -#define GTEST_ATTRIBUTE_UNUSED_ +#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED #endif // Use this annotation before a function that takes a printf format string. @@ -2108,8 +2129,9 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_() // defined there. #if GTEST_HAS_FILE_SYSTEM #if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \ - !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_ESP8266) && \ - !defined(GTEST_OS_XTENSA) && !defined(GTEST_OS_QURT) + !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \ + !defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) && \ + !defined(GTEST_OS_QURT) inline int ChDir(const char* dir) { return chdir(dir); } #endif inline FILE* FOpen(const char* path, const char* mode) { diff --git a/deps/googletest/src/gtest-death-test.cc b/deps/googletest/src/gtest-death-test.cc index 8417a300f7c73d..15472f1a7929cf 100644 --- a/deps/googletest/src/gtest-death-test.cc +++ b/deps/googletest/src/gtest-death-test.cc @@ -32,6 +32,8 @@ #include "gtest/gtest-death-test.h" +#include + #include #include #include @@ -115,7 +117,7 @@ GTEST_DEFINE_string_( GTEST_DEFINE_bool_( death_test_use_fork, testing::internal::BoolFromGTestEnv("death_test_use_fork", false), - "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Instructs to use fork()/_Exit() instead of clone() in death tests. " "Ignored and always uses fork() on POSIX systems where clone() is not " "implemented. Useful when running under valgrind or similar tools if " "those do not support clone(). Valgrind 3.3.1 will just fail if " @@ -299,7 +301,7 @@ enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; fputc(kDeathTestInternalError, parent); fprintf(parent, "%s", message.c_str()); fflush(parent); - _exit(1); + _Exit(1); } else { fprintf(stderr, "%s", message.c_str()); fflush(stderr); @@ -511,7 +513,7 @@ std::string DeathTestImpl::GetErrorLogs() { return GetCapturedStderr(); } // Signals that the death test code which should have exited, didn't. // Should be called only in a death test child process. // Writes a status byte to the child's status file descriptor, then -// calls _exit(1). +// calls _Exit(1). void DeathTestImpl::Abort(AbortReason reason) { // The parent process considers the death test to be a failure if // it finds any data in our pipe. So, here we write a single flag byte @@ -523,13 +525,13 @@ void DeathTestImpl::Abort(AbortReason reason) { GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); // We are leaking the descriptor here because on some platforms (i.e., // when built as Windows DLL), destructors of global objects will still - // run after calling _exit(). On such systems, write_fd_ will be + // run after calling _Exit(). On such systems, write_fd_ will be // indirectly closed from the destructor of UnitTestImpl, causing double // close if it is also closed here. On debug configurations, double close // may assert. As there are no in-process buffers to flush here, we are // relying on the OS to close the descriptor after the process terminates // when the destructors are not run. - _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) + _Exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) } // Returns an indented copy of stderr output for a death test. @@ -628,13 +630,13 @@ bool DeathTestImpl::Passed(bool status_ok) { #ifndef GTEST_OS_WINDOWS // Note: The return value points into args, so the return value's lifetime is // bound to that of args. -static std::unique_ptr CreateArgvFromArgs( - std::vector& args) { - auto result = std::make_unique(args.size() + 1); - for (size_t i = 0; i < args.size(); ++i) { - result[i] = &args[i][0]; +static std::vector CreateArgvFromArgs(std::vector& args) { + std::vector result; + result.reserve(args.size() + 1); + for (auto& arg : args) { + result.push_back(&arg[0]); } - result[args.size()] = nullptr; // extra null terminator + result.push_back(nullptr); // Extra null terminator. return result; } #endif @@ -1034,8 +1036,8 @@ DeathTest::TestRole FuchsiaDeathTest::AssumeRole() { // "Fuchsia Test Component" which contains a "Fuchsia Component Manifest") // Launching processes is a privileged operation in Fuchsia, and the // declaration indicates that the ability is required for the component. - std::unique_ptr argv = CreateArgvFromArgs(args); - status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.get(), + std::vector argv = CreateArgvFromArgs(args); + status = fdio_spawn_etc(child_job, FDIO_SPAWN_CLONE_ALL, argv[0], argv.data(), nullptr, 2, spawn_actions, child_process_.reset_and_get_address(), nullptr); GTEST_DEATH_TEST_CHECK_(status == ZX_OK); @@ -1333,7 +1335,7 @@ static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { #endif // GTEST_HAS_CLONE if (use_fork && (child_pid = fork()) == 0) { - _exit(ExecDeathTestChildMain(&args)); + _Exit(ExecDeathTestChildMain(&args)); } #endif // GTEST_OS_QNX #ifdef GTEST_OS_LINUX @@ -1386,8 +1388,8 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { // is necessary. FlushInfoLog(); - std::unique_ptr argv = CreateArgvFromArgs(args); - const pid_t child_pid = ExecDeathTestSpawnChild(argv.get(), pipe_fd[0]); + std::vector argv = CreateArgvFromArgs(args); + const pid_t child_pid = ExecDeathTestSpawnChild(argv.data(), pipe_fd[0]); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_child_pid(child_pid); set_read_fd(pipe_fd[0]); diff --git a/deps/googletest/src/gtest-internal-inl.h b/deps/googletest/src/gtest-internal-inl.h index 4799a1e7ba5d09..cc6f00488f9608 100644 --- a/deps/googletest/src/gtest-internal-inl.h +++ b/deps/googletest/src/gtest-internal-inl.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "gtest/internal/gtest-port.h" @@ -649,13 +650,15 @@ class GTEST_API_ UnitTestImpl { // this is not a typed or a type-parameterized test. // set_up_tc: pointer to the function that sets up the test suite // tear_down_tc: pointer to the function that tears down the test suite - TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param, + TestSuite* GetTestSuite(const std::string& test_suite_name, + const char* type_param, internal::SetUpTestSuiteFunc set_up_tc, internal::TearDownTestSuiteFunc tear_down_tc); // Legacy API is deprecated but still available #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - TestCase* GetTestCase(const char* test_case_name, const char* type_param, + TestCase* GetTestCase(const std::string& test_case_name, + const char* type_param, internal::SetUpTestSuiteFunc set_up_tc, internal::TearDownTestSuiteFunc tear_down_tc) { return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc); @@ -681,13 +684,13 @@ class GTEST_API_ UnitTestImpl { // AddTestInfo(), which is called to register a TEST or TEST_F // before main() is reached. if (original_working_dir_.IsEmpty()) { - original_working_dir_.Set(FilePath::GetCurrentDir()); + original_working_dir_ = FilePath::GetCurrentDir(); GTEST_CHECK_(!original_working_dir_.IsEmpty()) << "Failed to get the current working directory."; } #endif // GTEST_HAS_FILE_SYSTEM - GetTestSuite(test_info->test_suite_name(), test_info->type_param(), + GetTestSuite(test_info->test_suite_name_, test_info->type_param(), set_up_tc, tear_down_tc) ->AddTestInfo(test_info); } @@ -709,18 +712,6 @@ class GTEST_API_ UnitTestImpl { return type_parameterized_test_registry_; } - // Sets the TestSuite object for the test that's currently running. - void set_current_test_suite(TestSuite* a_current_test_suite) { - current_test_suite_ = a_current_test_suite; - } - - // Sets the TestInfo object for the test that's currently running. If - // current_test_info is NULL, the assertion results will be stored in - // ad_hoc_test_result_. - void set_current_test_info(TestInfo* a_current_test_info) { - current_test_info_ = a_current_test_info; - } - // Registers all parameterized tests defined using TEST_P and // INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter // combination. This method can be called more then once; it has guards @@ -835,12 +826,30 @@ class GTEST_API_ UnitTestImpl { bool catch_exceptions() const { return catch_exceptions_; } private: + struct CompareTestSuitesByPointer { + bool operator()(const TestSuite* lhs, const TestSuite* rhs) const { + return lhs->name_ < rhs->name_; + } + }; + friend class ::testing::UnitTest; // Used by UnitTest::Run() to capture the state of // GTEST_FLAG(catch_exceptions) at the moment it starts. void set_catch_exceptions(bool value) { catch_exceptions_ = value; } + // Sets the TestSuite object for the test that's currently running. + void set_current_test_suite(TestSuite* a_current_test_suite) { + current_test_suite_ = a_current_test_suite; + } + + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; + } + // The UnitTest object that owns this implementation object. UnitTest* const parent_; @@ -873,6 +882,9 @@ class GTEST_API_ UnitTestImpl { // elements in the vector. std::vector test_suites_; + // The set of TestSuites by name. + std::unordered_map test_suites_by_name_; + // Provides a level of indirection for the test suite list to allow // easy shuffling and restoring the test suite order. The i-th // element of this vector is the index of the i-th test suite in the diff --git a/deps/googletest/src/gtest-port.cc b/deps/googletest/src/gtest-port.cc index 3bb7dd450812d5..1038ad7bf60209 100644 --- a/deps/googletest/src/gtest-port.cc +++ b/deps/googletest/src/gtest-port.cc @@ -587,9 +587,11 @@ class ThreadLocalRegistryImpl { // thread's ID. typedef std::map ThreadIdToThreadLocals; - // Holds the thread id and thread handle that we pass from - // StartWatcherThreadFor to WatcherThreadFunc. - typedef std::pair ThreadIdAndHandle; + struct WatcherThreadParams { + DWORD thread_id; + HANDLE handle; + Notification has_initialized; + }; static void StartWatcherThreadFor(DWORD thread_id) { // The returned handle will be kept in thread_map and closed by @@ -597,15 +599,20 @@ class ThreadLocalRegistryImpl { HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id); GTEST_CHECK_(thread != nullptr); + + WatcherThreadParams* watcher_thread_params = new WatcherThreadParams; + watcher_thread_params->thread_id = thread_id; + watcher_thread_params->handle = thread; + // We need to pass a valid thread ID pointer into CreateThread for it // to work correctly under Win98. DWORD watcher_thread_id; - HANDLE watcher_thread = ::CreateThread( - nullptr, // Default security. - 0, // Default stack size - &ThreadLocalRegistryImpl::WatcherThreadFunc, - reinterpret_cast(new ThreadIdAndHandle(thread_id, thread)), - CREATE_SUSPENDED, &watcher_thread_id); + HANDLE watcher_thread = + ::CreateThread(nullptr, // Default security. + 0, // Default stack size + &ThreadLocalRegistryImpl::WatcherThreadFunc, + reinterpret_cast(watcher_thread_params), + CREATE_SUSPENDED, &watcher_thread_id); GTEST_CHECK_(watcher_thread != nullptr) << "CreateThread failed with error " << ::GetLastError() << "."; // Give the watcher thread the same priority as ours to avoid being @@ -614,17 +621,25 @@ class ThreadLocalRegistryImpl { ::GetThreadPriority(::GetCurrentThread())); ::ResumeThread(watcher_thread); ::CloseHandle(watcher_thread); + + // Wait for the watcher thread to start to avoid race conditions. + // One specific race condition that can happen is that we have returned + // from main and have started to tear down, the newly spawned watcher + // thread may access already-freed variables, like global shared_ptrs. + watcher_thread_params->has_initialized.WaitForNotification(); } // Monitors exit from a given thread and notifies those // ThreadIdToThreadLocals about thread termination. static DWORD WINAPI WatcherThreadFunc(LPVOID param) { - const ThreadIdAndHandle* tah = - reinterpret_cast(param); - GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); - OnThreadExit(tah->first); - ::CloseHandle(tah->second); - delete tah; + WatcherThreadParams* watcher_thread_params = + reinterpret_cast(param); + watcher_thread_params->has_initialized.Notify(); + GTEST_CHECK_(::WaitForSingleObject(watcher_thread_params->handle, + INFINITE) == WAIT_OBJECT_0); + OnThreadExit(watcher_thread_params->thread_id); + ::CloseHandle(watcher_thread_params->handle); + delete watcher_thread_params; return 0; } @@ -1033,12 +1048,12 @@ GTestLog::~GTestLog() { } } +#if GTEST_HAS_STREAM_REDIRECTION + // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) GTEST_DISABLE_MSC_DEPRECATED_PUSH_() -#if GTEST_HAS_STREAM_REDIRECTION - namespace { #if defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_IOS) @@ -1333,8 +1348,8 @@ bool ParseInt32(const Message& src_text, const char* str, int32_t* value) { ) { Message msg; msg << "WARNING: " << src_text - << " is expected to be a 32-bit integer, but actually" - << " has value " << str << ", which overflows.\n"; + << " is expected to be a 32-bit integer, but actually" << " has value " + << str << ", which overflows.\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; diff --git a/deps/googletest/src/gtest.cc b/deps/googletest/src/gtest.cc index 7dc80594362f5a..d64c18d7fd1a8d 100644 --- a/deps/googletest/src/gtest.cc +++ b/deps/googletest/src/gtest.cc @@ -379,7 +379,7 @@ GTEST_DEFINE_string_( testing::internal::StringFromGTestEnv("stream_result_to", ""), "This flag specifies the host name and the port number on which to stream " "test results. Example: \"localhost:555\". The flag is effective only on " - "Linux."); + "Linux and macOS."); GTEST_DEFINE_bool_( throw_on_failure, @@ -451,6 +451,19 @@ static bool ShouldRunTestSuite(const TestSuite* test_suite) { return test_suite->should_run(); } +namespace { + +// Returns true if test part results of type `type` should include a stack +// trace. +bool ShouldEmitStackTraceForResultType(TestPartResult::Type type) { + // Suppress emission of the stack trace for SUCCEED() since it likely never + // requires investigation, and GTEST_SKIP() since skipping is an intentional + // act by the developer rather than a failure requiring investigation. + return type != TestPartResult::kSuccess && type != TestPartResult::kSkip; +} + +} // namespace + // AssertHelper constructor. AssertHelper::AssertHelper(TestPartResult::Type type, const char* file, int line, const char* message) @@ -463,10 +476,7 @@ void AssertHelper::operator=(const Message& message) const { UnitTest::GetInstance()->AddTestPartResult( data_->type, data_->file, data_->line, AppendUserMessage(data_->message, message), - // Suppress emission of the stack trace for GTEST_SKIP() since skipping is - // an intentional act by the developer rather than a failure requiring - // investigation. - data_->type != TestPartResult::kSkip + ShouldEmitStackTraceForResultType(data_->type) ? UnitTest::GetInstance()->impl()->CurrentOsStackTraceExceptTop(1) : "" // Skips the stack frame for this function itself. @@ -526,7 +536,8 @@ void InsertSyntheticTestCase(const std::string& name, CodeLocation location, if (ignored.find(name) != ignored.end()) return; const char kMissingInstantiation[] = // - " is defined via TEST_P, but never instantiated. None of the test cases " + " is defined via TEST_P, but never instantiated. None of the test " + "cases " "will run. Either no INSTANTIATE_TEST_SUITE_P is provided or the only " "ones provided expand to nothing." "\n\n" @@ -567,7 +578,7 @@ void InsertSyntheticTestCase(const std::string& name, CodeLocation location, void RegisterTypeParameterizedTestSuite(const char* test_suite_name, CodeLocation code_location) { GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite( - test_suite_name, code_location); + test_suite_name, std::move(code_location)); } void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) { @@ -578,7 +589,7 @@ void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) { void TypeParameterizedTestSuiteRegistry::RegisterTestSuite( const char* test_suite_name, CodeLocation code_location) { suites_.emplace(std::string(test_suite_name), - TypeParameterizedTestSuiteInfo(code_location)); + TypeParameterizedTestSuiteInfo(std::move(code_location))); } void TypeParameterizedTestSuiteRegistry::RegisterInstantiation( @@ -605,10 +616,12 @@ void TypeParameterizedTestSuiteRegistry::CheckForInstantiations() { "\n\n" "Ideally, TYPED_TEST_P definitions should only ever be included as " "part of binaries that intend to use them. (As opposed to, for " - "example, being placed in a library that may be linked in to get other " + "example, being placed in a library that may be linked in to get " + "other " "utilities.)" "\n\n" - "To suppress this error for this test suite, insert the following line " + "To suppress this error for this test suite, insert the following " + "line " "(in a non-header) in the namespace it is defined in:" "\n\n" "GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" + @@ -788,7 +801,7 @@ class UnitTestFilter { // Returns true if and only if name matches at least one of the patterns in // the filter. bool MatchesName(const std::string& name) const { - return exact_match_patterns_.count(name) > 0 || + return exact_match_patterns_.find(name) != exact_match_patterns_.end() || std::any_of(glob_patterns_.begin(), glob_patterns_.end(), [&name](const std::string& pattern) { return PatternMatchesString( @@ -2327,7 +2340,7 @@ static const char* const kReservedTestCaseAttributes[] = { "type_param", "value_param", "file", "line"}; // Use a slightly different set for allowed output to ensure existing tests can -// still RecordProperty("result") or "RecordProperty(timestamp") +// still RecordProperty("result") or RecordProperty("timestamp") static const char* const kReservedOutputTestCaseAttributes[] = { "classname", "name", "status", "time", "type_param", "value_param", "file", "line", "result", "timestamp"}; @@ -2727,18 +2740,16 @@ bool Test::IsSkipped() { // Constructs a TestInfo object. It assumes ownership of the test factory // object. -TestInfo::TestInfo(const std::string& a_test_suite_name, - const std::string& a_name, const char* a_type_param, - const char* a_value_param, +TestInfo::TestInfo(std::string a_test_suite_name, std::string a_name, + const char* a_type_param, const char* a_value_param, internal::CodeLocation a_code_location, internal::TypeId fixture_class_id, internal::TestFactoryBase* factory) - : test_suite_name_(a_test_suite_name), - // begin()/end() is MSVC 17.3.3 ASAN crash workaround (GitHub issue #3997) - name_(a_name.begin(), a_name.end()), + : test_suite_name_(std::move(a_test_suite_name)), + name_(std::move(a_name)), type_param_(a_type_param ? new std::string(a_type_param) : nullptr), value_param_(a_value_param ? new std::string(a_value_param) : nullptr), - location_(a_code_location), + location_(std::move(a_code_location)), fixture_class_id_(fixture_class_id), should_run_(false), is_disabled_(false), @@ -2771,19 +2782,19 @@ namespace internal { // The newly created TestInfo instance will assume // ownership of the factory object. TestInfo* MakeAndRegisterTestInfo( - const char* test_suite_name, const char* name, const char* type_param, + std::string test_suite_name, const char* name, const char* type_param, const char* value_param, CodeLocation code_location, TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc, TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) { TestInfo* const test_info = - new TestInfo(test_suite_name, name, type_param, value_param, - code_location, fixture_class_id, factory); + new TestInfo(std::move(test_suite_name), name, type_param, value_param, + std::move(code_location), fixture_class_id, factory); GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); return test_info; } void ReportInvalidTestSuiteType(const char* test_suite_name, - CodeLocation code_location) { + const CodeLocation& code_location) { Message errors; errors << "Attempted redefinition of test suite " << test_suite_name << ".\n" @@ -2823,14 +2834,13 @@ void TestInfo::Run() { } // Tells UnitTest where to store test result. - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_info(this); + UnitTest::GetInstance()->set_current_test_info(this); // Notifies the unit test event listeners that a test is about to start. repeater->OnTestStart(*this); result_.set_start_timestamp(internal::GetTimeInMillis()); internal::Timer timer; - impl->os_stack_trace_getter()->UponLeavingGTest(); + UnitTest::GetInstance()->UponLeavingGTest(); // Creates the test object. Test* const test = internal::HandleExceptionsInMethodIfSupported( @@ -2848,7 +2858,7 @@ void TestInfo::Run() { if (test != nullptr) { // Deletes the test object. - impl->os_stack_trace_getter()->UponLeavingGTest(); + UnitTest::GetInstance()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( test, &Test::DeleteSelf_, "the test fixture's destructor"); } @@ -2860,15 +2870,14 @@ void TestInfo::Run() { // Tells UnitTest to stop associating assertion results to this // test. - impl->set_current_test_info(nullptr); + UnitTest::GetInstance()->set_current_test_info(nullptr); } // Skip and records a skipped test result for this object. void TestInfo::Skip() { if (!should_run_) return; - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_info(this); + UnitTest::GetInstance()->set_current_test_info(this); TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); @@ -2877,12 +2886,13 @@ void TestInfo::Skip() { const TestPartResult test_part_result = TestPartResult(TestPartResult::kSkip, this->file(), this->line(), ""); - impl->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult( - test_part_result); + internal::GetUnitTestImpl() + ->GetTestPartResultReporterForCurrentThread() + ->ReportTestPartResult(test_part_result); // Notifies the unit test event listener that a test has just finished. repeater->OnTestEnd(*this); - impl->set_current_test_info(nullptr); + UnitTest::GetInstance()->set_current_test_info(nullptr); } // class TestSuite @@ -2936,7 +2946,7 @@ int TestSuite::total_test_count() const { // this is not a typed or a type-parameterized test suite. // set_up_tc: pointer to the function that sets up the test suite // tear_down_tc: pointer to the function that tears down the test suite -TestSuite::TestSuite(const char* a_name, const char* a_type_param, +TestSuite::TestSuite(const std::string& a_name, const char* a_type_param, internal::SetUpTestSuiteFunc set_up_tc, internal::TearDownTestSuiteFunc tear_down_tc) : name_(a_name), @@ -2978,8 +2988,7 @@ void TestSuite::AddTestInfo(TestInfo* test_info) { void TestSuite::Run() { if (!should_run_) return; - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_suite(this); + UnitTest::GetInstance()->set_current_test_suite(this); TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); @@ -3009,7 +3018,7 @@ void TestSuite::Run() { repeater->OnTestCaseStart(*this); #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - impl->os_stack_trace_getter()->UponLeavingGTest(); + UnitTest::GetInstance()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()"); @@ -3034,7 +3043,7 @@ void TestSuite::Run() { } elapsed_time_ = timer.Elapsed(); - impl->os_stack_trace_getter()->UponLeavingGTest(); + UnitTest::GetInstance()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &TestSuite::RunTearDownTestSuite, "TearDownTestSuite()"); @@ -3045,15 +3054,14 @@ void TestSuite::Run() { repeater->OnTestCaseEnd(*this); #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - impl->set_current_test_suite(nullptr); + UnitTest::GetInstance()->set_current_test_suite(nullptr); } // Skips all tests under this TestSuite. void TestSuite::Skip() { if (!should_run_) return; - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_suite(this); + UnitTest::GetInstance()->set_current_test_suite(this); TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); @@ -3075,7 +3083,7 @@ void TestSuite::Skip() { repeater->OnTestCaseEnd(*this); #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ - impl->set_current_test_suite(nullptr); + UnitTest::GetInstance()->set_current_test_suite(nullptr); } // Clears the results of all tests in this test suite. @@ -3176,9 +3184,9 @@ static void PrintTestPartResult(const TestPartResult& test_part_result) { } // class PrettyUnitTestResultPrinter -#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \ - !defined(GTEST_OS_WINDOWS_PHONE) && !defined(GTEST_OS_WINDOWS_RT) && \ - !defined(GTEST_OS_WINDOWS_MINGW) +#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \ + !defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \ + !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW) // Returns the character attribute for the given color. static WORD GetColorAttribute(GTestColor color) { @@ -3262,6 +3270,7 @@ bool ShouldUseColor(bool stdout_is_tty) { term != nullptr && (String::CStringEquals(term, "xterm") || String::CStringEquals(term, "xterm-color") || String::CStringEquals(term, "xterm-kitty") || + String::CStringEquals(term, "alacritty") || String::CStringEquals(term, "screen") || String::CStringEquals(term, "tmux") || String::CStringEquals(term, "rxvt-unicode") || @@ -3304,9 +3313,9 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) { return; } -#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \ - !defined(GTEST_OS_WINDOWS_PHONE) && !defined(GTEST_OS_WINDOWS_RT) && \ - !defined(GTEST_OS_WINDOWS_MINGW) +#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \ + !defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \ + !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW) const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. @@ -4429,8 +4438,8 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( Message attributes; for (int i = 0; i < result.test_property_count(); ++i) { const TestProperty& property = result.GetTestProperty(i); - attributes << " " << property.key() << "=" - << "\"" << EscapeXmlAttribute(property.value()) << "\""; + attributes << " " << property.key() << "=" << "\"" + << EscapeXmlAttribute(property.value()) << "\""; } return attributes.GetString(); } @@ -4734,28 +4743,53 @@ void JsonUnitTestResultPrinter::OutputJsonTestResult(::std::ostream* stream, const TestResult& result) { const std::string kIndent = Indent(10); - int failures = 0; - for (int i = 0; i < result.total_part_count(); ++i) { - const TestPartResult& part = result.GetTestPartResult(i); - if (part.failed()) { - *stream << ",\n"; - if (++failures == 1) { - *stream << kIndent << "\"" - << "failures" - << "\": [\n"; + { + int failures = 0; + for (int i = 0; i < result.total_part_count(); ++i) { + const TestPartResult& part = result.GetTestPartResult(i); + if (part.failed()) { + *stream << ",\n"; + if (++failures == 1) { + *stream << kIndent << "\"" << "failures" << "\": [\n"; + } + const std::string location = + internal::FormatCompilerIndependentFileLocation(part.file_name(), + part.line_number()); + const std::string message = + EscapeJson(location + "\n" + part.message()); + *stream << kIndent << " {\n" + << kIndent << " \"failure\": \"" << message << "\",\n" + << kIndent << " \"type\": \"\"\n" + << kIndent << " }"; + } + } + + if (failures > 0) *stream << "\n" << kIndent << "]"; + } + + { + int skipped = 0; + for (int i = 0; i < result.total_part_count(); ++i) { + const TestPartResult& part = result.GetTestPartResult(i); + if (part.skipped()) { + *stream << ",\n"; + if (++skipped == 1) { + *stream << kIndent << "\"" << "skipped" << "\": [\n"; + } + const std::string location = + internal::FormatCompilerIndependentFileLocation(part.file_name(), + part.line_number()); + const std::string message = + EscapeJson(location + "\n" + part.message()); + *stream << kIndent << " {\n" + << kIndent << " \"message\": \"" << message << "\"\n" + << kIndent << " }"; } - const std::string location = - internal::FormatCompilerIndependentFileLocation(part.file_name(), - part.line_number()); - const std::string message = EscapeJson(location + "\n" + part.message()); - *stream << kIndent << " {\n" - << kIndent << " \"failure\": \"" << message << "\",\n" - << kIndent << " \"type\": \"\"\n" - << kIndent << " }"; } + + if (skipped > 0) *stream << "\n" << kIndent << "]"; } - if (failures > 0) *stream << "\n" << kIndent << "]"; *stream << "\n" << Indent(8) << "}"; } @@ -4892,8 +4926,8 @@ std::string JsonUnitTestResultPrinter::TestPropertiesAsJson( for (int i = 0; i < result.test_property_count(); ++i) { const TestProperty& property = result.GetTestProperty(i); attributes << ",\n" - << indent << "\"" << property.key() << "\": " - << "\"" << EscapeJson(property.value()) << "\""; + << indent << "\"" << property.key() << "\": " << "\"" + << EscapeJson(property.value()) << "\""; } return attributes.GetString(); } @@ -5291,6 +5325,22 @@ TestSuite* UnitTest::GetMutableTestSuite(int i) { return impl()->GetMutableSuiteCase(i); } +void UnitTest::UponLeavingGTest() { + impl()->os_stack_trace_getter()->UponLeavingGTest(); +} + +// Sets the TestSuite object for the test that's currently running. +void UnitTest::set_current_test_suite(TestSuite* a_current_test_suite) { + internal::MutexLock lock(&mutex_); + impl_->set_current_test_suite(a_current_test_suite); +} + +// Sets the TestInfo object for the test that's currently running. +void UnitTest::set_current_test_info(TestInfo* a_current_test_info) { + internal::MutexLock lock(&mutex_); + impl_->set_current_test_info(a_current_test_info); +} + // Returns the list of event listeners that can be used to track events // inside Google Test. TestEventListeners& UnitTest::listeners() { return *impl()->listeners(); } @@ -5450,7 +5500,7 @@ int UnitTest::Run() { // about crashes - they are expected. if (impl()->catch_exceptions() || in_death_test_child_process) { #if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \ - !defined(GTEST_OS_WINDOWS_RT) + !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); @@ -5720,29 +5770,6 @@ void UnitTestImpl::PostFlagParsingInit() { } } -// A predicate that checks the name of a TestSuite against a known -// value. -// -// This is used for implementation of the UnitTest class only. We put -// it in the anonymous namespace to prevent polluting the outer -// namespace. -// -// TestSuiteNameIs is copyable. -class TestSuiteNameIs { - public: - // Constructor. - explicit TestSuiteNameIs(const std::string& name) : name_(name) {} - - // Returns true if and only if the name of test_suite matches name_. - bool operator()(const TestSuite* test_suite) const { - return test_suite != nullptr && - strcmp(test_suite->name(), name_.c_str()) == 0; - } - - private: - std::string name_; -}; - // Finds and returns a TestSuite with the given name. If one doesn't // exist, creates one and returns it. It's the CALLER'S // RESPONSIBILITY to ensure that this function is only called WHEN THE @@ -5756,19 +5783,27 @@ class TestSuiteNameIs { // set_up_tc: pointer to the function that sets up the test suite // tear_down_tc: pointer to the function that tears down the test suite TestSuite* UnitTestImpl::GetTestSuite( - const char* test_suite_name, const char* type_param, + const std::string& test_suite_name, const char* type_param, internal::SetUpTestSuiteFunc set_up_tc, internal::TearDownTestSuiteFunc tear_down_tc) { - // Can we find a TestSuite with the given name? - const auto test_suite = - std::find_if(test_suites_.rbegin(), test_suites_.rend(), - TestSuiteNameIs(test_suite_name)); + // During initialization, all TestInfos for a given suite are added in + // sequence. To optimize this case, see if the most recently added suite is + // the one being requested now. + if (!test_suites_.empty() && + (*test_suites_.rbegin())->name_ == test_suite_name) { + return *test_suites_.rbegin(); + } - if (test_suite != test_suites_.rend()) return *test_suite; + // Fall back to searching the collection. + auto item_it = test_suites_by_name_.find(test_suite_name); + if (item_it != test_suites_by_name_.end()) { + return item_it->second; + } - // No. Let's create one. + // Not found. Create a new instance. auto* const new_test_suite = new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc); + test_suites_by_name_.emplace(test_suite_name, new_test_suite); const UnitTestFilter death_test_suite_filter(kDeathTestSuiteFilter); // Is this a death test suite? @@ -5981,6 +6016,12 @@ bool UnitTestImpl::RunAllTests() { } repeater->OnTestProgramEnd(*parent_); + // Destroy environments in normal code, not in static teardown. + bool delete_environment_on_teardown = true; + if (delete_environment_on_teardown) { + ForEach(environments_, internal::Delete); + environments_.clear(); + } if (!gtest_is_initialized_before_run_all_tests) { ColoredPrintf( @@ -6114,12 +6155,11 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { int num_runnable_tests = 0; int num_selected_tests = 0; for (auto* test_suite : test_suites_) { - const std::string& test_suite_name = test_suite->name(); + const std::string& test_suite_name = test_suite->name_; test_suite->set_should_run(false); - for (size_t j = 0; j < test_suite->test_info_list().size(); j++) { - TestInfo* const test_info = test_suite->test_info_list()[j]; - const std::string test_name(test_info->name()); + for (TestInfo* test_info : test_suite->test_info_list()) { + const std::string& test_name = test_info->name_; // A test is disabled if test suite name or test name matches // kDisableTestFilter. const bool is_disabled = diff --git a/deps/npm/bin/npm.ps1 b/deps/npm/bin/npm.ps1 index 399e33360e853c..04a1fd478ef9dd 100644 --- a/deps/npm/bin/npm.ps1 +++ b/deps/npm/bin/npm.ps1 @@ -1,35 +1,32 @@ #!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" +$NODE_EXE="$PSScriptRoot/node.exe" +if (-not (Test-Path $NODE_EXE)) { + $NODE_EXE="$PSScriptRoot/node" } -$ret=0 - -$nodeexe = "node$exe" -$nodebin = $(Get-Command $nodeexe -ErrorAction SilentlyContinue -ErrorVariable F).Source -if ($nodebin -eq $null) { - Write-Host "$nodeexe not found." - exit 1 +if (-not (Test-Path $NODE_EXE)) { + $NODE_EXE="node" } -$nodedir = $(New-Object -ComObject Scripting.FileSystemObject).GetFile("$nodebin").ParentFolder.Path -$npmprefixjs="$nodedir/node_modules/npm/bin/npm-prefix.js" -$npmprefix=(& $nodeexe $npmprefixjs) +$NPM_PREFIX_JS="$PSScriptRoot/node_modules/npm/bin/npm-prefix.js" +$NPM_CLI_JS="$PSScriptRoot/node_modules/npm/bin/npm-cli.js" +$NPM_PREFIX=(& $NODE_EXE $NPM_PREFIX_JS) + if ($LASTEXITCODE -ne 0) { Write-Host "Could not determine Node.js install directory" exit 1 } -$npmprefixclijs="$npmprefix/node_modules/npm/bin/npm-cli.js" + +$NPM_PREFIX_NPM_CLI_JS="$NPM_PREFIX/node_modules/npm/bin/npm-cli.js" +if (Test-Path $NPM_PREFIX_NPM_CLI_JS) { + $NPM_CLI_JS=$NPM_PREFIX_NPM_CLI_JS +} # Support pipeline input if ($MyInvocation.ExpectingInput) { - $input | & $nodeexe $npmprefixclijs $args + $input | & $NODE_EXE $NPM_CLI_JS $args } else { - & $nodeexe $npmprefixclijs $args + & $NODE_EXE $NPM_CLI_JS $args } -$ret=$LASTEXITCODE -exit $ret + +exit $LASTEXITCODE diff --git a/deps/npm/bin/npx-cli.js b/deps/npm/bin/npx-cli.js index 17d96fb26267c7..e2e1b87906abe0 100755 --- a/deps/npm/bin/npx-cli.js +++ b/deps/npm/bin/npx-cli.js @@ -26,7 +26,7 @@ const removed = new Set([ const { definitions, shorthands } = require('@npmcli/config/lib/definitions') const npmSwitches = Object.entries(definitions) - .filter(([key, { type }]) => type === Boolean || + .filter(([, { type }]) => type === Boolean || (Array.isArray(type) && type.includes(Boolean))) .map(([key]) => key) diff --git a/deps/npm/bin/npx.ps1 b/deps/npm/bin/npx.ps1 index 1d59fc52083d70..28dae51b22ca93 100644 --- a/deps/npm/bin/npx.ps1 +++ b/deps/npm/bin/npx.ps1 @@ -1,35 +1,32 @@ #!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent -$exe="" -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - # Fix case when both the Windows and Linux builds of Node - # are installed in the same directory - $exe=".exe" +$NODE_EXE="$PSScriptRoot/node.exe" +if (-not (Test-Path $NODE_EXE)) { + $NODE_EXE="$PSScriptRoot/node" } -$ret=0 - -$nodeexe = "node$exe" -$nodebin = $(Get-Command $nodeexe -ErrorAction SilentlyContinue -ErrorVariable F).Source -if ($nodebin -eq $null) { - Write-Host "$nodeexe not found." - exit 1 +if (-not (Test-Path $NODE_EXE)) { + $NODE_EXE="node" } -$nodedir = $(New-Object -ComObject Scripting.FileSystemObject).GetFile("$nodebin").ParentFolder.Path -$npmprefixjs="$nodedir/node_modules/npm/bin/npm-prefix.js" -$npmprefix=(& $nodeexe $npmprefixjs) +$NPM_PREFIX_JS="$PSScriptRoot/node_modules/npm/bin/npm-prefix.js" +$NPX_CLI_JS="$PSScriptRoot/node_modules/npm/bin/npx-cli.js" +$NPM_PREFIX=(& $NODE_EXE $NPM_PREFIX_JS) + if ($LASTEXITCODE -ne 0) { Write-Host "Could not determine Node.js install directory" exit 1 } -$npmprefixclijs="$npmprefix/node_modules/npm/bin/npx-cli.js" + +$NPM_PREFIX_NPX_CLI_JS="$NPM_PREFIX/node_modules/npm/bin/npx-cli.js" +if (Test-Path $NPM_PREFIX_NPX_CLI_JS) { + $NPX_CLI_JS=$NPM_PREFIX_NPX_CLI_JS +} # Support pipeline input if ($MyInvocation.ExpectingInput) { - $input | & $nodeexe $npmprefixclijs $args + $input | & $NODE_EXE $NPX_CLI_JS $args } else { - & $nodeexe $npmprefixclijs $args + & $NODE_EXE $NPX_CLI_JS $args } -$ret=$LASTEXITCODE -exit $ret + +exit $LASTEXITCODE diff --git a/deps/npm/docs/content/commands/npm-access.md b/deps/npm/docs/content/commands/npm-access.md index 9e9f385fe386de..e08030deba076d 100644 --- a/deps/npm/docs/content/commands/npm-access.md +++ b/deps/npm/docs/content/commands/npm-access.md @@ -7,7 +7,7 @@ description: Set access level on published packages ### Synopsis ```bash -npm access list packages [|| [] +npm access list packages [||] [] npm access list collaborators [ []] npm access get status [] npm access set status=public|private [] diff --git a/deps/npm/docs/content/commands/npm-doctor.md b/deps/npm/docs/content/commands/npm-doctor.md index b36ec3883be03a..a96036a773b2a1 100644 --- a/deps/npm/docs/content/commands/npm-doctor.md +++ b/deps/npm/docs/content/commands/npm-doctor.md @@ -7,7 +7,7 @@ description: Check the health of your npm environment ### Synopsis ```bash -npm doctor [ping] [registry] [versions] [environment] [permissions] [cache] +npm doctor [connection] [registry] [versions] [environment] [permissions] [cache] ``` Note: This command is unaware of workspaces. @@ -38,20 +38,21 @@ there are any recommended changes, it will display them. By default npm runs all of these checks. You can limit what checks are ran by specifying them as extra arguments. -#### `npm ping` +#### `Connecting to the registry` By default, npm installs from the primary npm registry, -`registry.npmjs.org`. `npm doctor` hits a special ping endpoint within the -registry. This can also be checked with `npm ping`. If this check fails, -you may be using a proxy that needs to be configured, or may need to talk -to your IT staff to get access over HTTPS to `registry.npmjs.org`. +`registry.npmjs.org`. `npm doctor` hits a special connection testing +endpoint within the registry. This can also be checked with `npm ping`. +If this check fails, you may be using a proxy that needs to be +configured, or may need to talk to your IT staff to get access over +HTTPS to `registry.npmjs.org`. This check is done against whichever registry you've configured (you can see what that is by running `npm config get registry`), and if you're using a private registry that doesn't support the `/whoami` endpoint supported by the primary registry, this check may fail. -#### `npm -v` +#### `Checking npm version` While Node.js may come bundled with a particular version of npm, it's the policy of the CLI team that we recommend all users run `npm@latest` if they @@ -61,7 +62,7 @@ support releases typically only receive critical security and regression fixes. The team believes that the latest tested version of npm is almost always likely to be the most functional and defect-free version of npm. -#### `node -v` +#### `Checking node version` For most users, in most circumstances, the best version of Node will be the latest long-term support (LTS) release. Those of you who want access to new @@ -70,7 +71,7 @@ be running a newer version, and some may be required to run an older version of Node because of enterprise change control policies. That's OK! But in general, the npm team recommends that most users run Node.js LTS. -#### `npm config get registry` +#### `Checking configured npm registry` You may be installing from private package registries for your project or company. That's great! Others may be following tutorials or StackOverflow @@ -79,7 +80,7 @@ Sometimes, this may entail changing the registry you're pointing at. This part of `npm doctor` just lets you, and maybe whoever's helping you with support, know that you're not using the default registry. -#### `which git` +#### `Checking for git executable in PATH` While it's documented in the README, it may not be obvious that npm needs Git installed to do many of the things that it does. Also, in some cases diff --git a/deps/npm/docs/content/commands/npm-ls.md b/deps/npm/docs/content/commands/npm-ls.md index 9c761e13fa34f0..89a4bd3604ce40 100644 --- a/deps/npm/docs/content/commands/npm-ls.md +++ b/deps/npm/docs/content/commands/npm-ls.md @@ -27,7 +27,7 @@ packages will *also* show the paths to the specified packages. For example, running `npm ls promzard` in npm's source tree will show: ```bash -npm@10.5.2 /path/to/npm +npm@10.7.0 /path/to/npm └─┬ init-package-json@0.0.4 └── promzard@0.1.5 ``` diff --git a/deps/npm/docs/content/commands/npm-profile.md b/deps/npm/docs/content/commands/npm-profile.md index d048532c98d452..2468d6c87faf60 100644 --- a/deps/npm/docs/content/commands/npm-profile.md +++ b/deps/npm/docs/content/commands/npm-profile.md @@ -24,28 +24,17 @@ support this interface. * `npm profile get []`: Display all of the properties of your profile, or one or more specific properties. It looks like: -```bash -+-----------------+---------------------------+ -| name | example | -+-----------------+---------------------------+ -| email | me@example.com (verified) | -+-----------------+---------------------------+ -| two factor auth | auth-and-writes | -+-----------------+---------------------------+ -| fullname | Example User | -+-----------------+---------------------------+ -| homepage | | -+-----------------+---------------------------+ -| freenode | | -+-----------------+---------------------------+ -| twitter | | -+-----------------+---------------------------+ -| github | | -+-----------------+---------------------------+ -| created | 2015-02-26T01:38:35.892Z | -+-----------------+---------------------------+ -| updated | 2017-10-02T21:29:45.922Z | -+-----------------+---------------------------+ +``` +name: example +email: e@example.com (verified) +two-factor auth: auth-and-writes +fullname: Example User +homepage: +freenode: +twitter: +github: +created: 2015-02-26T01:38:35.892Z +updated: 2017-10-02T21:29:45.922Z ``` * `npm profile set `: Set the value of a profile diff --git a/deps/npm/docs/content/commands/npm-search.md b/deps/npm/docs/content/commands/npm-search.md index 047102af61766e..4e4bbf58aec39e 100644 --- a/deps/npm/docs/content/commands/npm-search.md +++ b/deps/npm/docs/content/commands/npm-search.md @@ -7,7 +7,7 @@ description: Search for packages ### Synopsis ```bash -npm search [search terms ...] +npm search [ ...] aliases: find, s, se ``` @@ -39,15 +39,6 @@ expression characters in most shells.) ### Configuration -#### `long` - -* Default: false -* Type: Boolean - -Show extended information in `ls`, `search`, and `help-search`. - - - #### `json` * Default: false diff --git a/deps/npm/docs/content/commands/npm-token.md b/deps/npm/docs/content/commands/npm-token.md index a17193d5fe8d05..771da7d9857534 100644 --- a/deps/npm/docs/content/commands/npm-token.md +++ b/deps/npm/docs/content/commands/npm-token.md @@ -22,24 +22,14 @@ This lets you list, create and revoke authentication tokens. Shows a table of all active authentication tokens. You can request this as JSON with `--json` or tab-separated values with `--parseable`. -```bash -+--------+---------+------------+----------+----------------+ -| id | token | created | read-only | CIDR whitelist | -+--------+---------+------------+----------+----------------+ -| 7f3134 | 1fa9ba… | 2017-10-02 | yes | | -+--------+---------+------------+----------+----------------+ -| c03241 | af7aef… | 2017-10-02 | no | 192.168.0.1/24 | -+--------+---------+------------+----------+----------------+ -| e0cf92 | 3a436a… | 2017-10-02 | no | | -+--------+---------+------------+----------+----------------+ -| 63eb9d | 74ef35… | 2017-09-28 | no | | -+--------+---------+------------+----------+----------------+ -| 2daaa8 | cbad5f… | 2017-09-26 | no | | -+--------+---------+------------+----------+----------------+ -| 68c2fe | 127e51… | 2017-09-23 | no | | -+--------+---------+------------+----------+----------------+ -| 6334e1 | 1dadd1… | 2017-09-23 | no | | -+--------+---------+------------+----------+----------------+ +``` +Read only token npm_1f… with id 7f3134 created 2017-10-21 + +Publish token npm_af… with id c03241 created 2017-10-02 +with IP Whitelist: 192.168.0.1/24 + +Publish token npm_… with id e0cf92 created 2017-10-02 + ``` * `npm token create [--read-only] [--cidr=]`: @@ -55,16 +45,8 @@ This lets you list, create and revoke authentication tokens. website](https://docs.npmjs.com/creating-and-viewing-access-tokens) for more information on generating automation tokens. -```bash -+----------------+--------------------------------------+ -| token | a73c9572-f1b9-8983-983d-ba3ac3cc913d | -+----------------+--------------------------------------+ -| cidr_whitelist | | -+----------------+--------------------------------------+ -| readonly | false | -+----------------+--------------------------------------+ -| created | 2017-10-02T07:52:24.838Z | -+----------------+--------------------------------------+ +``` +Created publish token a73c9572-f1b9-8983-983d-ba3ac3cc913d ``` * `npm token revoke `: diff --git a/deps/npm/docs/content/commands/npm.md b/deps/npm/docs/content/commands/npm.md index 0e44e3e35e73f6..eb9a779cfdee9d 100644 --- a/deps/npm/docs/content/commands/npm.md +++ b/deps/npm/docs/content/commands/npm.md @@ -14,7 +14,7 @@ Note: This command is unaware of workspaces. ### Version -10.5.2 +10.7.0 ### Description diff --git a/deps/npm/docs/content/configuring-npm/package-json.md b/deps/npm/docs/content/configuring-npm/package-json.md index ec5cfcab1bb49e..43037477491e35 100644 --- a/deps/npm/docs/content/configuring-npm/package-json.md +++ b/deps/npm/docs/content/configuring-npm/package-json.md @@ -928,6 +928,13 @@ Overrides provide a way to replace a package in your dependency tree with another version, or another package entirely. These changes can be scoped as specific or as vague as desired. +Overrides are only considered in the root `package.json` file for a project. +Overrides in installed dependencies (including +[workspaces](/using-npm/workspaces)) are not considered in dependency tree +resolution. Published packages may dictate their resolutions by pinning +dependencies or using an +[`npm-shrinkwrap.json`](/configuring-npm/npm-shrinkwrap-json) file. + To make sure the package `foo` is always installed as version `1.0.0` no matter what version your dependencies rely on: diff --git a/deps/npm/docs/content/configuring-npm/package-lock-json.md b/deps/npm/docs/content/configuring-npm/package-lock-json.md index d540dd0e7228b8..f3b012175fa0ec 100644 --- a/deps/npm/docs/content/configuring-npm/package-lock-json.md +++ b/deps/npm/docs/content/configuring-npm/package-lock-json.md @@ -31,6 +31,8 @@ various purposes: picture of the package tree, reducing the need to read `package.json` files, and allowing for significant performance improvements. +When `npm` creates or updates `package-lock.json`, it will infer line endings and indentation from `package.json` so that the formatting of both files matches. + ### `package-lock.json` vs `npm-shrinkwrap.json` Both of these files have the same format, and perform similar functions in diff --git a/deps/npm/docs/lib/index.js b/deps/npm/docs/lib/index.js index 5d4ae7af3457bb..5f8501ead27b83 100644 --- a/deps/npm/docs/lib/index.js +++ b/deps/npm/docs/lib/index.js @@ -119,7 +119,7 @@ const replaceConfig = (src, { path }) => { } const allConfig = Object.entries(definitions).sort(sort) - .map(([_, def]) => def.describe()) + .map(([, def]) => def.describe()) .join('\n\n') return src.replace(replacer, allConfig) diff --git a/deps/npm/docs/output/commands/npm-access.html b/deps/npm/docs/output/commands/npm-access.html index aa89c3e0068fcf..3263227f8afd5f 100644 --- a/deps/npm/docs/output/commands/npm-access.html +++ b/deps/npm/docs/output/commands/npm-access.html @@ -146,7 +146,7 @@

Table of contents

Synopsis

-
npm access list packages [<user>|<scope>|<scope:team> [<package>]
+
npm access list packages [<user>|<scope>|<scope:team>] [<package>]
 npm access list collaborators [<package> [<user>]]
 npm access get status [<package>]
 npm access set status=public|private [<package>]
diff --git a/deps/npm/docs/output/commands/npm-doctor.html b/deps/npm/docs/output/commands/npm-doctor.html
index d63f33389af97e..fc4f7643fad896 100644
--- a/deps/npm/docs/output/commands/npm-doctor.html
+++ b/deps/npm/docs/output/commands/npm-doctor.html
@@ -142,11 +142,11 @@ 

npm-doctor

Table of contents

- +

Synopsis

-
npm doctor [ping] [registry] [versions] [environment] [permissions] [cache]
+
npm doctor [connection] [registry] [versions] [environment] [permissions] [cache]
 

Note: This command is unaware of workspaces.

Description

@@ -171,17 +171,18 @@

Description

there are any recommended changes, it will display them. By default npm runs all of these checks. You can limit what checks are ran by specifying them as extra arguments.

-

npm ping

+

Connecting to the registry

By default, npm installs from the primary npm registry, -registry.npmjs.org. npm doctor hits a special ping endpoint within the -registry. This can also be checked with npm ping. If this check fails, -you may be using a proxy that needs to be configured, or may need to talk -to your IT staff to get access over HTTPS to registry.npmjs.org.

+registry.npmjs.org. npm doctor hits a special connection testing +endpoint within the registry. This can also be checked with npm ping. +If this check fails, you may be using a proxy that needs to be +configured, or may need to talk to your IT staff to get access over +HTTPS to registry.npmjs.org.

This check is done against whichever registry you've configured (you can see what that is by running npm config get registry), and if you're using a private registry that doesn't support the /whoami endpoint supported by the primary registry, this check may fail.

-

npm -v

+

Checking npm version

While Node.js may come bundled with a particular version of npm, it's the policy of the CLI team that we recommend all users run npm@latest if they can. As the CLI is maintained by a small team of contributors, there are @@ -189,21 +190,21 @@

npm -v

support releases typically only receive critical security and regression fixes. The team believes that the latest tested version of npm is almost always likely to be the most functional and defect-free version of npm.

-

node -v

+

Checking node version

For most users, in most circumstances, the best version of Node will be the latest long-term support (LTS) release. Those of you who want access to new ECMAscript features or bleeding-edge changes to Node's standard library may be running a newer version, and some may be required to run an older version of Node because of enterprise change control policies. That's OK! But in general, the npm team recommends that most users run Node.js LTS.

-

npm config get registry

+

Checking configured npm registry

You may be installing from private package registries for your project or company. That's great! Others may be following tutorials or StackOverflow questions in an effort to troubleshoot problems you may be having. Sometimes, this may entail changing the registry you're pointing at. This part of npm doctor just lets you, and maybe whoever's helping you with support, know that you're not using the default registry.

-

which git

+

Checking for git executable in PATH

While it's documented in the README, it may not be obvious that npm needs Git installed to do many of the things that it does. Also, in some cases – especially on Windows – you may have Git set up in such a way that it's diff --git a/deps/npm/docs/output/commands/npm-ls.html b/deps/npm/docs/output/commands/npm-ls.html index 7449728edf37fe..be2287797a8f30 100644 --- a/deps/npm/docs/output/commands/npm-ls.html +++ b/deps/npm/docs/output/commands/npm-ls.html @@ -160,7 +160,7 @@

Description

the results to only the paths to the packages named. Note that nested packages will also show the paths to the specified packages. For example, running npm ls promzard in npm's source tree will show:

-
npm@10.5.2 /path/to/npm
+
npm@10.7.0 /path/to/npm
 └─┬ init-package-json@0.0.4
   └── promzard@0.1.5
 
diff --git a/deps/npm/docs/output/commands/npm-profile.html b/deps/npm/docs/output/commands/npm-profile.html index a6283aeb1884f8..e0c913a6b46b22 100644 --- a/deps/npm/docs/output/commands/npm-profile.html +++ b/deps/npm/docs/output/commands/npm-profile.html @@ -160,27 +160,16 @@

Description

  • npm profile get [<property>]: Display all of the properties of your profile, or one or more specific properties. It looks like:
  • -
    +-----------------+---------------------------+
    -| name            | example                   |
    -+-----------------+---------------------------+
    -| email           | me@example.com (verified) |
    -+-----------------+---------------------------+
    -| two factor auth | auth-and-writes           |
    -+-----------------+---------------------------+
    -| fullname        | Example User              |
    -+-----------------+---------------------------+
    -| homepage        |                           |
    -+-----------------+---------------------------+
    -| freenode        |                           |
    -+-----------------+---------------------------+
    -| twitter         |                           |
    -+-----------------+---------------------------+
    -| github          |                           |
    -+-----------------+---------------------------+
    -| created         | 2015-02-26T01:38:35.892Z  |
    -+-----------------+---------------------------+
    -| updated         | 2017-10-02T21:29:45.922Z  |
    -+-----------------+---------------------------+
    +
    name: example
    +email: e@example.com (verified)
    +two-factor auth: auth-and-writes
    +fullname: Example User
    +homepage:
    +freenode:
    +twitter:
    +github:
    +created: 2015-02-26T01:38:35.892Z
    +updated: 2017-10-02T21:29:45.922Z
     
    • diff --git a/deps/npm/docs/output/commands/npm-search.html b/deps/npm/docs/output/commands/npm-search.html index fb35290351bf63..3d7821531f730a 100644 --- a/deps/npm/docs/output/commands/npm-search.html +++ b/deps/npm/docs/output/commands/npm-search.html @@ -142,11 +142,11 @@

      npm-search

      Table of contents

      - +

      Synopsis

      -
      npm search [search terms ...]
      +
      npm search <search term> [<search term> ...]
       
       aliases: find, s, se
       
      @@ -170,12 +170,6 @@

      Description

      ignore a trailing / . (Note you must escape or quote many regular expression characters in most shells.)

      Configuration

      -

      long

      -
        -
      • Default: false
      • -
      • Type: Boolean
      • -
      -

      Show extended information in ls, search, and help-search.

      json

      • Default: false
      • diff --git a/deps/npm/docs/output/commands/npm-token.html b/deps/npm/docs/output/commands/npm-token.html index 44f94ec71ff14e..33b66d08e69def 100644 --- a/deps/npm/docs/output/commands/npm-token.html +++ b/deps/npm/docs/output/commands/npm-token.html @@ -158,23 +158,13 @@

        Description

        Shows a table of all active authentication tokens. You can request this as JSON with --json or tab-separated values with --parseable.
      -
      +--------+---------+------------+----------+----------------+
      -| id     | token   | created    | read-only | CIDR whitelist |
      -+--------+---------+------------+----------+----------------+
      -| 7f3134 | 1fa9ba… | 2017-10-02 | yes      |                |
      -+--------+---------+------------+----------+----------------+
      -| c03241 | af7aef… | 2017-10-02 | no       | 192.168.0.1/24 |
      -+--------+---------+------------+----------+----------------+
      -| e0cf92 | 3a436a… | 2017-10-02 | no       |                |
      -+--------+---------+------------+----------+----------------+
      -| 63eb9d | 74ef35… | 2017-09-28 | no       |                |
      -+--------+---------+------------+----------+----------------+
      -| 2daaa8 | cbad5f… | 2017-09-26 | no       |                |
      -+--------+---------+------------+----------+----------------+
      -| 68c2fe | 127e51… | 2017-09-23 | no       |                |
      -+--------+---------+------------+----------+----------------+
      -| 6334e1 | 1dadd1… | 2017-09-23 | no       |                |
      -+--------+---------+------------+----------+----------------+
      +
      Read only token npm_1f… with id 7f3134 created 2017-10-21
      +
      +Publish token npm_af…  with id c03241 created 2017-10-02
      +with IP Whitelist: 192.168.0.1/24
      +
      +Publish token npm_… with id e0cf92 created 2017-10-02
      +
       
      • @@ -191,15 +181,7 @@

        Description

        for more information on generating automation tokens.

      -
      +----------------+--------------------------------------+
      -| token          | a73c9572-f1b9-8983-983d-ba3ac3cc913d |
      -+----------------+--------------------------------------+
      -| cidr_whitelist |                                      |
      -+----------------+--------------------------------------+
      -| readonly       | false                                |
      -+----------------+--------------------------------------+
      -| created        | 2017-10-02T07:52:24.838Z             |
      -+----------------+--------------------------------------+
      +
      Created publish token a73c9572-f1b9-8983-983d-ba3ac3cc913d
       
      • npm token revoke <token|id>: diff --git a/deps/npm/docs/output/commands/npm.html b/deps/npm/docs/output/commands/npm.html index d79ded11c70ba2..1a279cf259db33 100644 --- a/deps/npm/docs/output/commands/npm.html +++ b/deps/npm/docs/output/commands/npm.html @@ -150,7 +150,7 @@

        Table of contents

      Note: This command is unaware of workspaces.

      Version

      -

      10.5.2

      +

      10.7.0

      Description

      npm is the package manager for the Node JavaScript platform. It puts modules in place so that node can find them, and manages dependency diff --git a/deps/npm/docs/output/configuring-npm/package-json.html b/deps/npm/docs/output/configuring-npm/package-json.html index becaa89251f049..3a0e58663c6ac7 100644 --- a/deps/npm/docs/output/configuring-npm/package-json.html +++ b/deps/npm/docs/output/configuring-npm/package-json.html @@ -850,6 +850,12 @@

      overrides

      Overrides provide a way to replace a package in your dependency tree with another version, or another package entirely. These changes can be scoped as specific or as vague as desired.

      +

      Overrides are only considered in the root package.json file for a project. +Overrides in installed dependencies (including +workspaces) are not considered in dependency tree +resolution. Published packages may dictate their resolutions by pinning +dependencies or using an +npm-shrinkwrap.json file.

      To make sure the package foo is always installed as version 1.0.0 no matter what version your dependencies rely on:

      {
      diff --git a/deps/npm/docs/output/configuring-npm/package-lock-json.html b/deps/npm/docs/output/configuring-npm/package-lock-json.html
      index 11e4ab79900e5a..ca61021db3a36a 100644
      --- a/deps/npm/docs/output/configuring-npm/package-lock-json.html
      +++ b/deps/npm/docs/output/configuring-npm/package-lock-json.html
      @@ -176,6 +176,7 @@ 

      Table of contents

      files, and allowing for significant performance improvements.

    +

    When npm creates or updates package-lock.json, it will infer line endings and indentation from package.json so that the formatting of both files matches.

    package-lock.json vs npm-shrinkwrap.json

    Both of these files have the same format, and perform similar functions in the root of a project.

    diff --git a/deps/npm/lib/arborist-cmd.js b/deps/npm/lib/arborist-cmd.js index 42699ece364ad1..9d247d02fa181d 100644 --- a/deps/npm/lib/arborist-cmd.js +++ b/deps/npm/lib/arborist-cmd.js @@ -1,10 +1,9 @@ -const log = require('./utils/log-shim.js') +const { log } = require('proc-log') +const BaseCommand = require('./base-cmd.js') // This is the base for all commands whose execWorkspaces just gets // a list of workspace names and passes it on to new Arborist() to // be able to run a filtered Arborist.reify() at some point. - -const BaseCommand = require('./base-command.js') class ArboristCmd extends BaseCommand { get isArboristCmd () { return true diff --git a/deps/npm/lib/base-command.js b/deps/npm/lib/base-cmd.js similarity index 93% rename from deps/npm/lib/base-command.js rename to deps/npm/lib/base-cmd.js index cdf7971b5aaf92..9c30ef8a4b44e0 100644 --- a/deps/npm/lib/base-command.js +++ b/deps/npm/lib/base-cmd.js @@ -1,10 +1,4 @@ -// Base class for npm commands - -const { relative } = require('path') - -const { definitions } = require('@npmcli/config/lib/definitions') -const { aliases: cmdAliases } = require('./utils/cmd-list') -const log = require('./utils/log-shim.js') +const { log, output } = require('proc-log') class BaseCommand { static workspaces = false @@ -18,6 +12,8 @@ class BaseCommand { // this is a static so that we can read from it without instantiating a command // which would require loading the config static get describeUsage () { + const { definitions } = require('@npmcli/config/lib/definitions') + const { aliases: cmdAliases } = require('./utils/cmd-list') const seenExclusive = new Set() const wrapWidth = 80 const { description, usage = [''], name, params } = this @@ -119,7 +115,7 @@ class BaseCommand { const { config } = this.npm if (config.get('usage')) { - return this.npm.output(this.usage) + return output.standard(this.usage) } const hasWsConfig = config.get('workspaces') || config.get('workspace').length @@ -161,6 +157,8 @@ class BaseCommand { } async setWorkspaces () { + const { relative } = require('node:path') + const includeWorkspaceRoot = this.isArboristCmd ? false : this.npm.config.get('include-workspace-root') @@ -169,7 +167,7 @@ class BaseCommand { const relativeFrom = prefixInsideCwd ? this.npm.localPrefix : process.cwd() const filters = this.npm.config.get('workspace') - const getWorkspaces = require('./workspaces/get-workspaces.js') + const getWorkspaces = require('./utils/get-workspaces.js') const ws = await getWorkspaces(filters, { path: this.npm.localPrefix, includeWorkspaceRoot, @@ -181,4 +179,5 @@ class BaseCommand { this.workspacePaths = [...ws.values()] } } + module.exports = BaseCommand diff --git a/deps/npm/lib/cli.js b/deps/npm/lib/cli.js index c85ecb65a7005a..e11729fe3205b9 100644 --- a/deps/npm/lib/cli.js +++ b/deps/npm/lib/cli.js @@ -1,4 +1,4 @@ -const validateEngines = require('./es6/validate-engines.js') -const cliEntry = require('path').resolve(__dirname, 'cli-entry.js') +const validateEngines = require('./cli/validate-engines.js') +const cliEntry = require('node:path').resolve(__dirname, 'cli/entry.js') module.exports = (process) => validateEngines(process, () => require(cliEntry)) diff --git a/deps/npm/lib/cli-entry.js b/deps/npm/lib/cli/entry.js similarity index 56% rename from deps/npm/lib/cli-entry.js rename to deps/npm/lib/cli/entry.js index aad06e06903856..5d676c3f0a8a10 100644 --- a/deps/npm/lib/cli-entry.js +++ b/deps/npm/lib/cli/entry.js @@ -11,14 +11,17 @@ module.exports = async (process, validateEngines) => { process.argv.splice(1, 1, 'npm', '-g') } + // Patch the global fs module here at the app level + require('graceful-fs').gracefulify(require('fs')) + const satisfies = require('semver/functions/satisfies') - const exitHandler = require('./utils/exit-handler.js') - const Npm = require('./npm.js') + const exitHandler = require('./exit-handler.js') + const Npm = require('../npm.js') const npm = new Npm() exitHandler.setNpm(npm) // only log node and npm paths in argv initially since argv can contain sensitive info. a cleaned version will be logged later - const log = require('./utils/log-shim.js') + const { log, output } = require('proc-log') log.verbose('cli', process.argv.slice(0, 2).join(' ')) log.info('using', 'npm@%s', npm.version) log.info('using', 'node@%s', process.version) @@ -33,39 +36,49 @@ module.exports = async (process, validateEngines) => { log.warn('cli', validateEngines.unsupportedMessage) } - let cmd // Now actually fire up npm and run the command. // This is how to use npm programmatically: try { - await npm.load() + const { exec, command, args } = await npm.load() - // npm -v - if (npm.config.get('version', 'cli')) { - npm.output(npm.version) + if (!exec) { return exitHandler() } - // npm --versions - if (npm.config.get('versions', 'cli')) { - npm.argv = ['version'] - npm.config.set('usage', false, 'cli') - } - - cmd = npm.argv.shift() - if (!cmd) { - npm.output(npm.usage) + if (!command) { + output.standard(npm.usage) process.exitCode = 1 return exitHandler() } - await npm.exec(cmd) + // Options are prefixed by a hyphen-minus (-, \u2d). + // Other dash-type chars look similar but are invalid. + const nonDashArgs = npm.argv.filter(a => /^[\u2010-\u2015\u2212\uFE58\uFE63\uFF0D]/.test(a)) + if (nonDashArgs.length) { + log.error( + 'arg', + 'Argument starts with non-ascii dash, this is probably invalid:', + require('@npmcli/redact').redactLog(nonDashArgs.join(', ')) + ) + } + + const execPromise = npm.exec(command, args) + + // this is async but we dont await it, since its ok if it doesnt + // finish before the command finishes running. it uses command and argv + // so it must be initiated here, after the command name is set + const updateNotifier = require('./update-notifier.js') + // eslint-disable-next-line promise/catch-or-return + updateNotifier(npm).then((msg) => (npm.updateNotification = msg)) + + await execPromise return exitHandler() } catch (err) { if (err.code === 'EUNKNOWNCOMMAND') { - const didYouMean = require('./utils/did-you-mean.js') - const suggestions = await didYouMean(npm.localPrefix, cmd) - npm.output(`Unknown command: "${cmd}"${suggestions}\n`) - npm.output('To see a list of supported npm commands, run:\n npm help') + const didYouMean = require('../utils/did-you-mean.js') + const suggestions = await didYouMean(npm.localPrefix, err.command) + output.standard(`Unknown command: "${err.command}"${suggestions}\n`) + output.standard('To see a list of supported npm commands, run:\n npm help') process.exitCode = 1 return exitHandler() } diff --git a/deps/npm/lib/utils/exit-handler.js b/deps/npm/lib/cli/exit-handler.js similarity index 65% rename from deps/npm/lib/utils/exit-handler.js rename to deps/npm/lib/cli/exit-handler.js index 8b4ab45c4d4745..5866c46b57c5f0 100644 --- a/deps/npm/lib/utils/exit-handler.js +++ b/deps/npm/lib/cli/exit-handler.js @@ -1,8 +1,5 @@ -const os = require('os') -const fs = require('fs') - -const log = require('./log-shim.js') -const errorMessage = require('./error-message.js') +const { log, output, META } = require('proc-log') +const errorMessage = require('../utils/error-message.js') const { redactLog: replaceInfo } = require('@npmcli/redact') let npm = null // set by the cli @@ -10,21 +7,8 @@ let exitHandlerCalled = false let showLogFileError = false process.on('exit', code => { - log.disableProgress() - - // process.emit is synchronous, so the timeEnd handler will run before the - // unfinished timer check below - process.emit('timeEnd', 'npm') - const hasLoadedNpm = npm?.config.loaded - // Unfinished timers can be read before config load - if (npm) { - for (const [name, timer] of npm.unfinishedTimers) { - log.verbose('unfinished npm timer', name, timer) - } - } - if (!code) { log.info('ok') } else { @@ -34,66 +18,16 @@ process.on('exit', code => { if (!exitHandlerCalled) { process.exitCode = code || 1 log.error('', 'Exit handler never called!') - // eslint-disable-next-line no-console - console.error('') log.error('', 'This is an error with npm itself. Please report this error at:') log.error('', ' ') + // eslint-disable-next-line no-console + console.error('') showLogFileError = true } // npm must be loaded to know where the log file was written if (hasLoadedNpm) { - // write the timing file now, this might do nothing based on the configs set. - // we need to call it here in case it errors so we dont tell the user - // about a timing file that doesn't exist - npm.writeTimingFile() - - const logsDir = npm.logsDir - const logFiles = npm.logFiles - - const timingDir = npm.timingDir - const timingFile = npm.timingFile - - const timing = npm.config.get('timing') - const logsMax = npm.config.get('logs-max') - - // Determine whether to show log file message and why it is - // being shown since in timing mode we always show the log file message - const logMethod = showLogFileError ? 'error' : timing ? 'info' : null - - if (logMethod) { - if (!npm.silent) { - // just a line break if not in silent mode - // eslint-disable-next-line no-console - console.error('') - } - - const message = [] - - if (timingFile) { - message.push(`Timing info written to: ${timingFile}`) - } else if (timing) { - message.push( - `The timing file was not written due to an error writing to the directory: ${timingDir}` - ) - } - - if (logFiles.length) { - message.push(`A complete log of this run can be found in: ${logFiles}`) - } else if (logsMax <= 0) { - // user specified no log file - message.push(`Log files were not written due to the config logs-max=${logsMax}`) - } else { - // could be an error writing to the directory - message.push( - `Log files were not written due to an error writing to the directory: ${logsDir}`, - 'You can rerun the command with `--loglevel=verbose` to see the logs in your terminal' - ) - } - - log[logMethod]('', message.join('\n')) - } - + npm.finish({ showLogFileError }) // This removes any listeners npm setup, mostly for tests to avoid max listener warnings npm.unload() } @@ -106,12 +40,11 @@ process.on('exit', code => { const exitHandler = err => { exitHandlerCalled = true - log.disableProgress() - const hasLoadedNpm = npm?.config.loaded if (!npm) { err = err || new Error('Exit prior to setting npm in exit handler') + // Don't use proc-log here since npm was never set // eslint-disable-next-line no-console console.error(err.stack || err.message) return process.exit(1) @@ -119,16 +52,14 @@ const exitHandler = err => { if (!hasLoadedNpm) { err = err || new Error('Exit prior to config file resolving.') + // Don't use proc-log here since npm was never loaded // eslint-disable-next-line no-console console.error(err.stack || err.message) } // only show the notification if it finished. if (typeof npm.updateNotification === 'string') { - const { level } = log - log.level = 'notice' - log.notice('', npm.updateNotification) - log.level = level + log.notice('', npm.updateNotification, { [META]: true, force: true }) } let exitCode = process.exitCode || 0 @@ -154,6 +85,8 @@ const exitHandler = err => { log.error('weird error', err) noLogMessage = true } else { + const os = require('node:os') + const fs = require('node:fs') if (!err.code) { const matchErrorCode = err.message.match(/^(?:Error: )?(E[A-Z]+)/) err.code = matchErrorCode && matchErrorCode[1] @@ -205,7 +138,7 @@ const exitHandler = err => { } if (hasLoadedNpm) { - npm.flushOutput(jsonError) + output.flush({ [META]: true, jsonError }) } log.verbose('exit', exitCode || 0) diff --git a/deps/npm/lib/utils/update-notifier.js b/deps/npm/lib/cli/update-notifier.js similarity index 86% rename from deps/npm/lib/utils/update-notifier.js rename to deps/npm/lib/cli/update-notifier.js index 7481b65d562217..41fece36a558eb 100644 --- a/deps/npm/lib/utils/update-notifier.js +++ b/deps/npm/lib/cli/update-notifier.js @@ -49,7 +49,6 @@ const updateCheck = async (npm, spec, version, current) => { return null } - const useColor = npm.logColor const chalk = npm.logChalk // ok! notify the user about this update they should get. @@ -60,19 +59,14 @@ const updateCheck = async (npm, spec, version, current) => { : update.minor !== current.minor ? 'minor' : update.patch !== current.patch ? 'patch' : 'prerelease' - const typec = type === 'major' ? chalk.red(type) - : type === 'minor' ? chalk.yellow(type) - : chalk.green(type) - const oldc = chalk.red(current) - const latestc = chalk.green(latest) - const changelog = `https://github.com/npm/cli/releases/tag/v${latest}` - const changelogc = !useColor ? `<${changelog}>` : chalk.cyan(changelog) + const typec = type === 'major' ? 'red' + : type === 'minor' ? 'yellow' + : 'cyan' const cmd = `npm install -g npm@${latest}` - const cmdc = !useColor ? `\`${cmd}\`` : chalk.green(cmd) - const message = `\nNew ${typec} version of npm available! ` + - `${oldc} -> ${latestc}\n` + - `Changelog: ${changelogc}\n` + - `Run ${cmdc} to update!\n` + const message = `\nNew ${chalk[typec](type)} version of npm available! ` + + `${chalk[typec](current)} -> ${chalk.blue(latest)}\n` + + `Changelog: ${chalk.blue(`https://github.com/npm/cli/releases/tag/v${latest}`)}\n` + + `To update run: ${chalk.underline(cmd)}\n` return message } diff --git a/deps/npm/lib/es6/validate-engines.js b/deps/npm/lib/cli/validate-engines.js similarity index 100% rename from deps/npm/lib/es6/validate-engines.js rename to deps/npm/lib/cli/validate-engines.js diff --git a/deps/npm/lib/commands/access.js b/deps/npm/lib/commands/access.js index 99c1264a84eda3..d35699e839109c 100644 --- a/deps/npm/lib/commands/access.js +++ b/deps/npm/lib/commands/access.js @@ -1,11 +1,11 @@ const libnpmaccess = require('libnpmaccess') const npa = require('npm-package-arg') +const { output } = require('proc-log') const pkgJson = require('@npmcli/package-json') const localeCompare = require('@isaacs/string-locale-compare')('en') - const otplease = require('../utils/otplease.js') const getIdentity = require('../utils/get-identity.js') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') const commands = [ 'get', @@ -36,7 +36,7 @@ class Access extends BaseCommand { ] static usage = [ - 'list packages [|| []', + 'list packages [||] []', 'list collaborators [ []]', 'get status []', 'set status=public|private []', @@ -197,7 +197,7 @@ class Access extends BaseCommand { } #output (items, limiter) { - const output = {} + const outputs = {} const lookup = { __proto__: null, read: 'read-only', @@ -205,14 +205,14 @@ class Access extends BaseCommand { } for (const item in items) { const val = items[item] - output[item] = lookup[val] || val + outputs[item] = lookup[val] || val } if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify(output, null, 2)) + output.standard(JSON.stringify(outputs, null, 2)) } else { - for (const item of Object.keys(output).sort(localeCompare)) { + for (const item of Object.keys(outputs).sort(localeCompare)) { if (!limiter || limiter === item) { - this.npm.output(`${item}: ${output[item]}`) + output.standard(`${item}: ${outputs[item]}`) } } } diff --git a/deps/npm/lib/commands/adduser.js b/deps/npm/lib/commands/adduser.js index a69ef366fbf32c..cf64e7a7e74389 100644 --- a/deps/npm/lib/commands/adduser.js +++ b/deps/npm/lib/commands/adduser.js @@ -1,8 +1,7 @@ -const log = require('../utils/log-shim.js') +const { log, output } = require('proc-log') const { redactLog: replaceInfo } = require('@npmcli/redact') const auth = require('../utils/auth.js') - -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') class AddUser extends BaseCommand { static description = 'Add a registry user account' @@ -13,7 +12,7 @@ class AddUser extends BaseCommand { 'auth-type', ] - async exec (args) { + async exec () { const scope = this.npm.config.get('scope') let registry = this.npm.config.get('registry') @@ -27,7 +26,6 @@ class AddUser extends BaseCommand { const creds = this.npm.config.getCredentialsByURI(registry) - log.disableProgress() log.notice('', `Log in on ${replaceInfo(registry)}`) const { message, newCreds } = await auth.adduser(this.npm, { @@ -45,7 +43,8 @@ class AddUser extends BaseCommand { await this.npm.config.save('user') - this.npm.output(message) + output.standard(message) } } + module.exports = AddUser diff --git a/deps/npm/lib/commands/audit.js b/deps/npm/lib/commands/audit.js index 8c10a36cfee3cf..aed1be7a82906b 100644 --- a/deps/npm/lib/commands/audit.js +++ b/deps/npm/lib/commands/audit.js @@ -1,399 +1,9 @@ const npmAuditReport = require('npm-audit-report') -const fetch = require('npm-registry-fetch') -const localeCompare = require('@isaacs/string-locale-compare')('en') -const npa = require('npm-package-arg') -const pacote = require('pacote') -const pMap = require('p-map') -const tufClient = require('@sigstore/tuf') - const ArboristWorkspaceCmd = require('../arborist-cmd.js') const auditError = require('../utils/audit-error.js') -const log = require('../utils/log-shim.js') +const { log, output } = require('proc-log') const reifyFinish = require('../utils/reify-finish.js') - -const sortAlphabetically = (a, b) => localeCompare(a.name, b.name) - -class VerifySignatures { - constructor (tree, filterSet, npm, opts) { - this.tree = tree - this.filterSet = filterSet - this.npm = npm - this.opts = opts - this.keys = new Map() - this.invalid = [] - this.missing = [] - this.checkedPackages = new Set() - this.auditedWithKeysCount = 0 - this.verifiedSignatureCount = 0 - this.verifiedAttestationCount = 0 - this.exitCode = 0 - } - - async run () { - const start = process.hrtime.bigint() - - // Find all deps in tree - const { edges, registries } = this.getEdgesOut(this.tree.inventory.values(), this.filterSet) - if (edges.size === 0) { - throw new Error('found no installed dependencies to audit') - } - - const tuf = await tufClient.initTUF({ - cachePath: this.opts.tufCache, - retry: this.opts.retry, - timeout: this.opts.timeout, - }) - await Promise.all([...registries].map(registry => this.setKeys({ registry, tuf }))) - - const progress = log.newItem('verifying registry signatures', edges.size) - const mapper = async (edge) => { - progress.completeWork(1) - await this.getVerifiedInfo(edge) - } - await pMap(edges, mapper, { concurrency: 20, stopOnError: true }) - - // Didn't find any dependencies that could be verified, e.g. only local - // deps, missing version, not on a registry etc. - if (!this.auditedWithKeysCount) { - throw new Error('found no dependencies to audit that were installed from ' + - 'a supported registry') - } - - const invalid = this.invalid.sort(sortAlphabetically) - const missing = this.missing.sort(sortAlphabetically) - - const hasNoInvalidOrMissing = invalid.length === 0 && missing.length === 0 - - if (!hasNoInvalidOrMissing) { - process.exitCode = 1 - } - - if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify({ - invalid, - missing, - }, null, 2)) - return - } - const end = process.hrtime.bigint() - const elapsed = end - start - - const auditedPlural = this.auditedWithKeysCount > 1 ? 's' : '' - const timing = `audited ${this.auditedWithKeysCount} package${auditedPlural} in ` + - `${Math.floor(Number(elapsed) / 1e9)}s` - this.npm.output(timing) - this.npm.output('') - - const verifiedBold = this.npm.chalk.bold('verified') - if (this.verifiedSignatureCount) { - if (this.verifiedSignatureCount === 1) { - /* eslint-disable-next-line max-len */ - this.npm.output(`${this.verifiedSignatureCount} package has a ${verifiedBold} registry signature`) - } else { - /* eslint-disable-next-line max-len */ - this.npm.output(`${this.verifiedSignatureCount} packages have ${verifiedBold} registry signatures`) - } - this.npm.output('') - } - - if (this.verifiedAttestationCount) { - if (this.verifiedAttestationCount === 1) { - /* eslint-disable-next-line max-len */ - this.npm.output(`${this.verifiedAttestationCount} package has a ${verifiedBold} attestation`) - } else { - /* eslint-disable-next-line max-len */ - this.npm.output(`${this.verifiedAttestationCount} packages have ${verifiedBold} attestations`) - } - this.npm.output('') - } - - if (missing.length) { - const missingClr = this.npm.chalk.bold(this.npm.chalk.red('missing')) - if (missing.length === 1) { - /* eslint-disable-next-line max-len */ - this.npm.output(`1 package has a ${missingClr} registry signature but the registry is providing signing keys:`) - } else { - /* eslint-disable-next-line max-len */ - this.npm.output(`${missing.length} packages have ${missingClr} registry signatures but the registry is providing signing keys:`) - } - this.npm.output('') - missing.map(m => - this.npm.output(`${this.npm.chalk.red(`${m.name}@${m.version}`)} (${m.registry})`) - ) - } - - if (invalid.length) { - if (missing.length) { - this.npm.output('') - } - const invalidClr = this.npm.chalk.bold(this.npm.chalk.red('invalid')) - // We can have either invalid signatures or invalid provenance - const invalidSignatures = this.invalid.filter(i => i.code === 'EINTEGRITYSIGNATURE') - if (invalidSignatures.length) { - if (invalidSignatures.length === 1) { - this.npm.output(`1 package has an ${invalidClr} registry signature:`) - } else { - /* eslint-disable-next-line max-len */ - this.npm.output(`${invalidSignatures.length} packages have ${invalidClr} registry signatures:`) - } - this.npm.output('') - invalidSignatures.map(i => - this.npm.output(`${this.npm.chalk.red(`${i.name}@${i.version}`)} (${i.registry})`) - ) - this.npm.output('') - } - - const invalidAttestations = this.invalid.filter(i => i.code === 'EATTESTATIONVERIFY') - if (invalidAttestations.length) { - if (invalidAttestations.length === 1) { - this.npm.output(`1 package has an ${invalidClr} attestation:`) - } else { - /* eslint-disable-next-line max-len */ - this.npm.output(`${invalidAttestations.length} packages have ${invalidClr} attestations:`) - } - this.npm.output('') - invalidAttestations.map(i => - this.npm.output(`${this.npm.chalk.red(`${i.name}@${i.version}`)} (${i.registry})`) - ) - this.npm.output('') - } - - if (invalid.length === 1) { - /* eslint-disable-next-line max-len */ - this.npm.output(`Someone might have tampered with this package since it was published on the registry!`) - } else { - /* eslint-disable-next-line max-len */ - this.npm.output(`Someone might have tampered with these packages since they were published on the registry!`) - } - this.npm.output('') - } - } - - getEdgesOut (nodes, filterSet) { - const edges = new Set() - const registries = new Set() - for (const node of nodes) { - for (const edge of node.edgesOut.values()) { - const filteredOut = - edge.from - && filterSet - && filterSet.size > 0 - && !filterSet.has(edge.from.target) - - if (!filteredOut) { - const spec = this.getEdgeSpec(edge) - if (spec) { - // Prefetch and cache public keys from used registries - registries.add(this.getSpecRegistry(spec)) - } - edges.add(edge) - } - } - } - return { edges, registries } - } - - async setKeys ({ registry, tuf }) { - const { host, pathname } = new URL(registry) - // Strip any trailing slashes from pathname - const regKey = `${host}${pathname.replace(/\/$/, '')}/keys.json` - let keys = await tuf.getTarget(regKey) - .then((target) => JSON.parse(target)) - .then(({ keys: ks }) => ks.map((key) => ({ - ...key, - keyid: key.keyId, - pemkey: `-----BEGIN PUBLIC KEY-----\n${key.publicKey.rawBytes}\n-----END PUBLIC KEY-----`, - expires: key.publicKey.validFor.end || null, - }))).catch(err => { - if (err.code === 'TUF_FIND_TARGET_ERROR') { - return null - } else { - throw err - } - }) - - // If keys not found in Sigstore TUF repo, fallback to registry keys API - if (!keys) { - keys = await fetch.json('/-/npm/v1/keys', { - ...this.npm.flatOptions, - registry, - }).then(({ keys: ks }) => ks.map((key) => ({ - ...key, - pemkey: `-----BEGIN PUBLIC KEY-----\n${key.key}\n-----END PUBLIC KEY-----`, - }))).catch(err => { - if (err.code === 'E404' || err.code === 'E400') { - return null - } else { - throw err - } - }) - } - - if (keys) { - this.keys.set(registry, keys) - } - } - - getEdgeType (edge) { - return edge.optional ? 'optionalDependencies' - : edge.peer ? 'peerDependencies' - : edge.dev ? 'devDependencies' - : 'dependencies' - } - - getEdgeSpec (edge) { - let name = edge.name - try { - name = npa(edge.spec).subSpec.name - } catch { - // leave it as edge.name - } - try { - return npa(`${name}@${edge.spec}`) - } catch { - // Skip packages with invalid spec - } - } - - buildRegistryConfig (registry) { - const keys = this.keys.get(registry) || [] - const parsedRegistry = new URL(registry) - const regKey = `//${parsedRegistry.host}${parsedRegistry.pathname}` - return { - [`${regKey}:_keys`]: keys, - } - } - - getSpecRegistry (spec) { - return fetch.pickRegistry(spec, this.npm.flatOptions) - } - - getValidPackageInfo (edge) { - const type = this.getEdgeType(edge) - // Skip potentially optional packages that are not on disk, as these could - // be omitted during install - if (edge.error === 'MISSING' && type !== 'dependencies') { - return - } - - const spec = this.getEdgeSpec(edge) - // Skip invalid version requirements - if (!spec) { - return - } - const node = edge.to || edge - const { version } = node.package || {} - - if (node.isWorkspace || // Skip local workspaces packages - !version || // Skip packages that don't have a installed version, e.g. optonal dependencies - !spec.registry) { // Skip if not from registry, e.g. git package - return - } - - for (const omitType of this.npm.config.get('omit')) { - if (node[omitType]) { - return - } - } - - return { - name: spec.name, - version, - type, - location: node.location, - registry: this.getSpecRegistry(spec), - } - } - - async verifySignatures (name, version, registry) { - const { - _integrity: integrity, - _signatures, - _attestations, - _resolved: resolved, - } = await pacote.manifest(`${name}@${version}`, { - verifySignatures: true, - verifyAttestations: true, - ...this.buildRegistryConfig(registry), - ...this.npm.flatOptions, - }) - const signatures = _signatures || [] - const result = { - integrity, - signatures, - attestations: _attestations, - resolved, - } - return result - } - - async getVerifiedInfo (edge) { - const info = this.getValidPackageInfo(edge) - if (!info) { - return - } - const { name, version, location, registry, type } = info - if (this.checkedPackages.has(location)) { - // we already did or are doing this one - return - } - this.checkedPackages.add(location) - - // We only "audit" or verify the signature, or the presence of it, on - // packages whose registry returns signing keys - const keys = this.keys.get(registry) || [] - if (keys.length) { - this.auditedWithKeysCount += 1 - } - - try { - const { integrity, signatures, attestations, resolved } = await this.verifySignatures( - name, version, registry - ) - - // Currently we only care about missing signatures on registries that provide a public key - // We could make this configurable in the future with a strict/paranoid mode - if (signatures.length) { - this.verifiedSignatureCount += 1 - } else if (keys.length) { - this.missing.push({ - integrity, - location, - name, - registry, - resolved, - version, - }) - } - - // Track verified attestations separately to registry signatures, as all - // packages on registries with signing keys are expected to have registry - // signatures, but not all packages have provenance and publish attestations. - if (attestations) { - this.verifiedAttestationCount += 1 - } - } catch (e) { - if (e.code === 'EINTEGRITYSIGNATURE' || e.code === 'EATTESTATIONVERIFY') { - this.invalid.push({ - code: e.code, - message: e.message, - integrity: e.integrity, - keyid: e.keyid, - location, - name, - registry, - resolved: e.resolved, - signature: e.signature, - predicateType: e.predicateType, - type, - version, - }) - } else { - throw e - } - } - } -} +const VerifySignatures = require('../utils/verify-signatures.js') class Audit extends ArboristWorkspaceCmd { static description = 'Run a security audit' @@ -467,7 +77,7 @@ class Audit extends ArboristWorkspaceCmd { chalk: this.npm.chalk, }) process.exitCode = process.exitCode || result.exitCode - this.npm.output(result.report) + output.standard(result.report) } } diff --git a/deps/npm/lib/commands/cache.js b/deps/npm/lib/commands/cache.js index 50bb35e3544dfe..108c261ffe57d5 100644 --- a/deps/npm/lib/commands/cache.js +++ b/deps/npm/lib/commands/cache.js @@ -3,11 +3,11 @@ const pacote = require('pacote') const fs = require('fs/promises') const { join } = require('path') const semver = require('semver') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') const npa = require('npm-package-arg') const jsonParse = require('json-parse-even-better-errors') const localeCompare = require('@isaacs/string-locale-compare')('en') -const log = require('../utils/log-shim') +const { log, output } = require('proc-log') const searchCachePackage = async (path, parsed, cacheKeys) => { /* eslint-disable-next-line max-len */ @@ -135,7 +135,7 @@ class Cache extends BaseCommand { log.warn(`Not Found: ${key}`) break } - this.npm.output(`Deleted: ${key}`) + output.standard(`Deleted: ${key}`) await cacache.rm.entry(cachePath, key) // XXX this could leave other entries without content! await cacache.rm.content(cachePath, entry.integrity) @@ -170,20 +170,20 @@ class Cache extends BaseCommand { ? `~${cache.slice(process.env.HOME.length)}` : cache const stats = await cacache.verify(cache) - this.npm.output(`Cache verified and compressed (${prefix})`) - this.npm.output(`Content verified: ${stats.verifiedContent} (${stats.keptSize} bytes)`) + output.standard(`Cache verified and compressed (${prefix})`) + output.standard(`Content verified: ${stats.verifiedContent} (${stats.keptSize} bytes)`) if (stats.badContentCount) { - this.npm.output(`Corrupted content removed: ${stats.badContentCount}`) + output.standard(`Corrupted content removed: ${stats.badContentCount}`) } if (stats.reclaimedCount) { /* eslint-disable-next-line max-len */ - this.npm.output(`Content garbage-collected: ${stats.reclaimedCount} (${stats.reclaimedSize} bytes)`) + output.standard(`Content garbage-collected: ${stats.reclaimedCount} (${stats.reclaimedSize} bytes)`) } if (stats.missingContent) { - this.npm.output(`Missing content: ${stats.missingContent}`) + output.standard(`Missing content: ${stats.missingContent}`) } - this.npm.output(`Index entries: ${stats.totalEntries}`) - this.npm.output(`Finished in ${stats.runTime.total / 1000}s`) + output.standard(`Index entries: ${stats.totalEntries}`) + output.standard(`Finished in ${stats.runTime.total / 1000}s`) } // npm cache ls [--package ...] @@ -203,10 +203,10 @@ class Cache extends BaseCommand { results.add(key) } } - [...results].sort(localeCompare).forEach(key => this.npm.output(key)) + [...results].sort(localeCompare).forEach(key => output.standard(key)) return } - cacheKeys.sort(localeCompare).forEach(key => this.npm.output(key)) + cacheKeys.sort(localeCompare).forEach(key => output.standard(key)) } } diff --git a/deps/npm/lib/commands/ci.js b/deps/npm/lib/commands/ci.js index 428c43e6c30edc..7e79d7208c9c4b 100644 --- a/deps/npm/lib/commands/ci.js +++ b/deps/npm/lib/commands/ci.js @@ -1,9 +1,8 @@ const reifyFinish = require('../utils/reify-finish.js') const runScript = require('@npmcli/run-script') const fs = require('fs/promises') -const log = require('../utils/log-shim.js') +const { log, time } = require('proc-log') const validateLockfile = require('../utils/validate-lockfile.js') - const ArboristWorkspaceCmd = require('../arborist-cmd.js') class CI extends ArboristWorkspaceCmd { @@ -79,10 +78,10 @@ class CI extends ArboristWorkspaceCmd { if (!dryRun) { // Only remove node_modules after we've successfully loaded the virtual // tree and validated the lockfile - await this.npm.time('npm-ci:rm', async () => { + await time.start('npm-ci:rm', async () => { const path = `${where}/node_modules` // get the list of entries so we can skip the glob for performance - const entries = await fs.readdir(path, null).catch(er => []) + const entries = await fs.readdir(path, null).catch(() => []) return Promise.all(entries.map(f => fs.rm(`${path}/${f}`, { force: true, recursive: true }))) }) @@ -109,7 +108,6 @@ class CI extends ArboristWorkspaceCmd { args: [], scriptShell, stdio: 'inherit', - banner: !this.npm.silent, event, }) } diff --git a/deps/npm/lib/commands/completion.js b/deps/npm/lib/commands/completion.js index 59113c50560bca..9b147d2f5bdac6 100644 --- a/deps/npm/lib/commands/completion.js +++ b/deps/npm/lib/commands/completion.js @@ -27,22 +27,22 @@ // Matches are wrapped with ' to escape them, if necessary, and then printed // one per line for the shell completion method to consume in IFS=$'\n' mode // as an array. -// const fs = require('fs/promises') const nopt = require('nopt') const { resolve } = require('path') - +const { output } = require('proc-log') const Npm = require('../npm.js') const { definitions, shorthands } = require('@npmcli/config/lib/definitions') const { commands, aliases, deref } = require('../utils/cmd-list.js') -const configNames = Object.keys(definitions) -const shorthandNames = Object.keys(shorthands) -const allConfs = configNames.concat(shorthandNames) const { isWindowsShell } = require('../utils/is-windows.js') +const BaseCommand = require('../base-cmd.js') + const fileExists = (file) => fs.stat(file).then(s => s.isFile()).catch(() => false) -const BaseCommand = require('../base-command.js') +const configNames = Object.keys(definitions) +const shorthandNames = Object.keys(shorthands) +const allConfs = configNames.concat(shorthandNames) class Completion extends BaseCommand { static description = 'Tab Completion for npm' @@ -185,7 +185,7 @@ class Completion extends BaseCommand { } if (compls.length > 0) { - this.npm.output(compls.join('\n')) + output.standard(compls.join('\n')) } } } @@ -248,7 +248,7 @@ const configCompl = opts => { // expand with the valid values of various config values. // not yet implemented. -const configValueCompl = opts => [] +const configValueCompl = () => [] // check if the thing is a flag or not. const isFlag = word => { @@ -265,7 +265,7 @@ const isFlag = word => { // complete against the npm commands // if they all resolve to the same thing, just return the thing it already is -const cmdCompl = (opts, npm) => { +const cmdCompl = (opts) => { const allCommands = commands.concat(Object.keys(aliases)) const matches = allCommands.filter(c => c.startsWith(opts.partialWord)) if (!matches.length) { diff --git a/deps/npm/lib/commands/config.js b/deps/npm/lib/commands/config.js index 8e8358fc50b7be..7fb8476276937b 100644 --- a/deps/npm/lib/commands/config.js +++ b/deps/npm/lib/commands/config.js @@ -1,12 +1,12 @@ -const { mkdir, readFile, writeFile } = require('fs/promises') -const { dirname, resolve } = require('path') -const { spawn } = require('child_process') -const { EOL } = require('os') -const ini = require('ini') +const { mkdir, readFile, writeFile } = require('node:fs/promises') +const { dirname, resolve } = require('node:path') +const { spawn } = require('node:child_process') +const { EOL } = require('node:os') const localeCompare = require('@isaacs/string-locale-compare')('en') const pkgJson = require('@npmcli/package-json') const { defaults, definitions } = require('@npmcli/config/lib/definitions') -const log = require('../utils/log-shim.js') +const { log, output } = require('proc-log') +const BaseCommand = require('../base-cmd.js') // These are the configs that we can nerf-dart. Not all of them currently even // *have* config definitions so we have to explicitly validate them here @@ -47,7 +47,6 @@ const publicVar = k => { return true } -const BaseCommand = require('../base-command.js') class Config extends BaseCommand { static description = 'Manage the npm configuration files' static name = 'config' @@ -111,35 +110,30 @@ class Config extends BaseCommand { } async exec ([action, ...args]) { - log.disableProgress() - try { - switch (action) { - case 'set': - await this.set(args) - break - case 'get': - await this.get(args) - break - case 'delete': - case 'rm': - case 'del': - await this.del(args) - break - case 'list': - case 'ls': - await (this.npm.flatOptions.json ? this.listJson() : this.list()) - break - case 'edit': - await this.edit() - break - case 'fix': - await this.fix() - break - default: - throw this.usageError() - } - } finally { - log.enableProgress() + switch (action) { + case 'set': + await this.set(args) + break + case 'get': + await this.get(args) + break + case 'delete': + case 'rm': + case 'del': + await this.del(args) + break + case 'list': + case 'ls': + await (this.npm.flatOptions.json ? this.listJson() : this.list()) + break + case 'edit': + await this.edit() + break + case 'fix': + await this.fix() + break + default: + throw this.usageError() } } @@ -190,7 +184,7 @@ class Config extends BaseCommand { const pref = keys.length > 1 ? `${key}=` : '' out.push(pref + this.npm.config.get(key)) } - this.npm.output(out.join('\n')) + output.standard(out.join('\n')) } async del (keys) { @@ -206,6 +200,7 @@ class Config extends BaseCommand { } async edit () { + const ini = require('ini') const e = this.npm.flatOptions.editor const where = this.npm.flatOptions.location const file = this.npm.config.data.get(where).source @@ -287,7 +282,7 @@ ${defData} this.npm.config.repair(problems) const locations = [] - this.npm.output('The following configuration problems have been repaired:\n') + output.standard('The following configuration problems have been repaired:\n') const summary = problems.map(({ action, from, to, key, where }) => { // coverage disabled for else branch because it is intentionally omitted // istanbul ignore else @@ -300,7 +295,7 @@ ${defData} return `- \`${key}\` deleted from ${where} config` } }).join('\n') - this.npm.output(summary) + output.standard(summary) return await Promise.all(locations.map((location) => this.npm.config.save(location))) } @@ -359,7 +354,7 @@ ${defData} } } - this.npm.output(msg.join('\n').trim()) + output.standard(msg.join('\n').trim()) } async listJson () { @@ -371,7 +366,7 @@ ${defData} publicConf[key] = this.npm.config.get(key) } - this.npm.output(JSON.stringify(publicConf, null, 2)) + output.standard(JSON.stringify(publicConf, null, 2)) } } diff --git a/deps/npm/lib/commands/dedupe.js b/deps/npm/lib/commands/dedupe.js index 0d0e26621b2275..e07bcd31e894b9 100644 --- a/deps/npm/lib/commands/dedupe.js +++ b/deps/npm/lib/commands/dedupe.js @@ -1,8 +1,7 @@ -// dedupe duplicated packages, or find them in the tree const reifyFinish = require('../utils/reify-finish.js') - const ArboristWorkspaceCmd = require('../arborist-cmd.js') +// dedupe duplicated packages, or find them in the tree class Dedupe extends ArboristWorkspaceCmd { static description = 'Reduce duplication in the package tree' static name = 'dedupe' @@ -22,7 +21,7 @@ class Dedupe extends ArboristWorkspaceCmd { ...super.params, ] - async exec (args) { + async exec () { if (this.npm.global) { const er = new Error('`npm dedupe` does not work in global mode.') er.code = 'EDEDUPEGLOBAL' diff --git a/deps/npm/lib/commands/deprecate.js b/deps/npm/lib/commands/deprecate.js index bdce313923cff8..58856538fe23f2 100644 --- a/deps/npm/lib/commands/deprecate.js +++ b/deps/npm/lib/commands/deprecate.js @@ -4,7 +4,7 @@ const npa = require('npm-package-arg') const semver = require('semver') const getIdentity = require('../utils/get-identity.js') const libaccess = require('libnpmaccess') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') class Deprecate extends BaseCommand { static description = 'Deprecate a version of a package' diff --git a/deps/npm/lib/commands/diff.js b/deps/npm/lib/commands/diff.js index 64d81d525d79d2..ca8b1237b40c5a 100644 --- a/deps/npm/lib/commands/diff.js +++ b/deps/npm/lib/commands/diff.js @@ -4,9 +4,9 @@ const libnpmdiff = require('libnpmdiff') const npa = require('npm-package-arg') const pacote = require('pacote') const pickManifest = require('npm-pick-manifest') -const log = require('../utils/log-shim') +const { log, output } = require('proc-log') const pkgJson = require('@npmcli/package-json') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') class Diff extends BaseCommand { static description = 'The registry diff command' @@ -64,7 +64,7 @@ class Diff extends BaseCommand { diffFiles: args, where: this.top, }) - return this.npm.output(res) + return output.standard(res) } async execWorkspaces (args) { @@ -78,7 +78,7 @@ class Diff extends BaseCommand { // get the package name from the packument at `path` // throws if no packument is present OR if it does not have `name` attribute - async packageName (path) { + async packageName () { let name try { const { content: pkg } = await pkgJson.normalize(this.prefix) @@ -103,7 +103,7 @@ class Diff extends BaseCommand { // no arguments, defaults to comparing cwd // to its latest published registry version if (!a) { - const pkgName = await this.packageName(this.prefix) + const pkgName = await this.packageName() return [ `${pkgName}@${this.npm.config.get('tag')}`, `file:${this.prefix.replace(/#/g, '%23')}`, diff --git a/deps/npm/lib/commands/dist-tag.js b/deps/npm/lib/commands/dist-tag.js index ff49bc8e307cb6..e13f9ecf59c7fe 100644 --- a/deps/npm/lib/commands/dist-tag.js +++ b/deps/npm/lib/commands/dist-tag.js @@ -1,10 +1,10 @@ const npa = require('npm-package-arg') const regFetch = require('npm-registry-fetch') const semver = require('semver') -const log = require('../utils/log-shim') +const { log, output } = require('proc-log') const otplease = require('../utils/otplease.js') const pkgJson = require('@npmcli/package-json') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') class DistTag extends BaseCommand { static description = 'Modify package distribution tags' @@ -120,7 +120,7 @@ class DistTag extends BaseCommand { spec, } await otplease(this.npm, reqOpts, o => regFetch(url, o)) - this.npm.output(`+${t}: ${spec.name}@${version}`) + output.standard(`+${t}: ${spec.name}@${version}`) } async remove (spec, tag, opts) { @@ -146,7 +146,7 @@ class DistTag extends BaseCommand { spec, } await otplease(this.npm, reqOpts, o => regFetch(url, o)) - this.npm.output(`-${tag}: ${spec.name}@${version}`) + output.standard(`-${tag}: ${spec.name}@${version}`) } async list (spec, opts) { @@ -167,7 +167,7 @@ class DistTag extends BaseCommand { const tags = await this.fetchTags(spec, opts) const msg = Object.keys(tags).map(k => `${k}: ${tags[k]}`).sort().join('\n') - this.npm.output(msg) + output.standard(msg) return tags } catch (err) { log.error('dist-tag ls', "Couldn't get dist-tag data for", spec) @@ -180,7 +180,7 @@ class DistTag extends BaseCommand { for (const name of this.workspaceNames) { try { - this.npm.output(`${name}:`) + output.standard(`${name}:`) await this.list(npa(name), this.npm.flatOptions) } catch (err) { // set the exitCode directly, but ignore the error @@ -205,4 +205,5 @@ class DistTag extends BaseCommand { return data } } + module.exports = DistTag diff --git a/deps/npm/lib/commands/docs.js b/deps/npm/lib/commands/docs.js index 5d20215b56a07f..2259b49f79617f 100644 --- a/deps/npm/lib/commands/docs.js +++ b/deps/npm/lib/commands/docs.js @@ -1,4 +1,5 @@ const PackageUrlCmd = require('../package-url-cmd.js') + class Docs extends PackageUrlCmd { static description = 'Open documentation for a package in a web browser' static name = 'docs' @@ -16,4 +17,5 @@ class Docs extends PackageUrlCmd { return `https://www.npmjs.com/package/${mani.name}` } } + module.exports = Docs diff --git a/deps/npm/lib/commands/doctor.js b/deps/npm/lib/commands/doctor.js index 2a528d46ddb8dc..c29dd7e0ecb174 100644 --- a/deps/npm/lib/commands/doctor.js +++ b/deps/npm/lib/commands/doctor.js @@ -1,19 +1,14 @@ const cacache = require('cacache') -const fs = require('fs') +const { access, lstat, readdir, constants: { R_OK, W_OK, X_OK } } = require('fs/promises') const fetch = require('make-fetch-happen') -const Table = require('cli-table3') const which = require('which') const pacote = require('pacote') const { resolve } = require('path') const semver = require('semver') -const { promisify } = require('util') -const log = require('../utils/log-shim.js') +const { log, output } = require('proc-log') const ping = require('../utils/ping.js') const { defaults } = require('@npmcli/config/lib/definitions') -const lstat = promisify(fs.lstat) -const readdir = promisify(fs.readdir) -const access = promisify(fs.access) -const { R_OK, W_OK, X_OK } = fs.constants +const BaseCommand = require('../base-cmd.js') const maskLabel = mask => { const label = [] @@ -34,57 +29,59 @@ const maskLabel = mask => { const subcommands = [ { - groups: ['ping', 'registry'], - title: 'npm ping', + // Ping is left in as a legacy command but is listed as "connection" to + // make more sense to more people + groups: ['connection', 'ping', 'registry'], + title: 'Connecting to the registry', cmd: 'checkPing', }, { groups: ['versions'], - title: 'npm -v', + title: 'Checking npm version', cmd: 'getLatestNpmVersion', }, { groups: ['versions'], - title: 'node -v', + title: 'Checking node version', cmd: 'getLatestNodejsVersion', }, { groups: ['registry'], - title: 'npm config get registry', + title: 'Checking configured npm registry', cmd: 'checkNpmRegistry', }, { groups: ['environment'], - title: 'git executable in PATH', + title: 'Checking for git executable in PATH', cmd: 'getGitPath', }, { groups: ['environment'], - title: 'global bin folder in PATH', + title: 'Checking for global bin folder in PATH', cmd: 'getBinPath', }, { groups: ['permissions', 'cache'], - title: 'Perms check on cached files', + title: 'Checking permissions on cached files (this may take awhile)', cmd: 'checkCachePermission', windows: false, }, { groups: ['permissions'], - title: 'Perms check on local node_modules', + title: 'Checking permissions on local node_modules (this may take awhile)', cmd: 'checkLocalModulesPermission', windows: false, }, { groups: ['permissions'], - title: 'Perms check on global node_modules', + title: 'Checking permissions on global node_modules (this may take awhile)', cmd: 'checkGlobalModulesPermission', windows: false, }, { groups: ['permissions'], - title: 'Perms check on local bin folder', + title: 'Checking permissions on local bin folder', cmd: 'checkLocalBinPermission', windows: false, }, { groups: ['permissions'], - title: 'Perms check on global bin folder', + title: 'Checking permissions on global bin folder', cmd: 'checkGlobalBinPermission', windows: false, }, { groups: ['cache'], - title: 'Verify cache contents', + title: 'Verifying cache contents (this may take awhile)', cmd: 'verifyCachedFiles', windows: false, }, @@ -97,50 +94,35 @@ const subcommands = [ // - verify all local packages have bins linked // What is the fix for these? ] -const BaseCommand = require('../base-command.js') + class Doctor extends BaseCommand { static description = 'Check the health of your npm environment' static name = 'doctor' static params = ['registry'] static ignoreImplicitWorkspace = false static usage = [`[${subcommands.flatMap(s => s.groups) - .filter((value, index, self) => self.indexOf(value) === index) + .filter((value, index, self) => self.indexOf(value) === index && value !== 'ping') .join('] [')}]`] static subcommands = subcommands - // minimum width of check column, enough for the word `Check` - #checkWidth = 5 - async exec (args) { - log.info('Running checkup') + log.info('doctor', 'Running checkup') let allOk = true const actions = this.actions(args) - this.#checkWidth = actions.reduce((length, item) => - Math.max(item.title.length, length), this.#checkWidth) - if (!this.npm.silent) { - this.output(['Check', 'Value', 'Recommendation/Notes'].map(h => this.npm.chalk.underline(h))) - } - // Do the actual work + const chalk = this.npm.chalk for (const { title, cmd } of actions) { - const item = [title] + this.output(title) + // TODO when we have an in progress indicator that could go here + let result try { - item.push(true, await this[cmd]()) + result = await this[cmd]() + this.output(`${chalk.green('Ok')}${result ? `\n${result}` : ''}\n`) } catch (err) { - item.push(false, err) - } - 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') - } - if (!this.npm.silent) { - this.output(item) + this.output(`${chalk.red('Not ok')}\n${chalk.cyan(err)}\n`) } } @@ -155,8 +137,7 @@ class Doctor extends BaseCommand { } async checkPing () { - const tracker = log.newItem('checkPing', 1) - tracker.info('checkPing', 'Pinging registry') + log.info('doctor', 'Pinging registry') try { await ping({ ...this.npm.flatOptions, retry: false }) return '' @@ -166,23 +147,16 @@ class Doctor extends BaseCommand { } else { throw er.message } - } finally { - tracker.finish() } } async getLatestNpmVersion () { - const tracker = log.newItem('getLatestNpmVersion', 1) - tracker.info('getLatestNpmVersion', 'Getting npm package information') - try { - const latest = (await pacote.manifest('npm@latest', this.npm.flatOptions)).version - if (semver.gte(this.npm.version, latest)) { - return `current: v${this.npm.version}, latest: v${latest}` - } else { - throw `Use npm v${latest}` - } - } finally { - tracker.finish() + log.info('doctor', 'Getting npm package information') + const latest = (await pacote.manifest('npm@latest', this.npm.flatOptions)).version + if (semver.gte(this.npm.version, latest)) { + return `current: v${this.npm.version}, latest: v${latest}` + } else { + throw `Use npm v${latest}` } } @@ -191,36 +165,30 @@ class Doctor extends BaseCommand { const current = process.version const currentRange = `^${current}` const url = 'https://nodejs.org/dist/index.json' - const tracker = log.newItem('getLatestNodejsVersion', 1) - tracker.info('getLatestNodejsVersion', 'Getting Node.js release information') - try { - const res = await fetch(url, { method: 'GET', ...this.npm.flatOptions }) - const data = await res.json() - let maxCurrent = '0.0.0' - let maxLTS = '0.0.0' - for (const { lts, version } of data) { - if (lts && semver.gt(version, maxLTS)) { - maxLTS = version - } - - if (semver.satisfies(version, currentRange) && semver.gt(version, maxCurrent)) { - maxCurrent = version - } + log.info('doctor', 'Getting Node.js release information') + const res = await fetch(url, { method: 'GET', ...this.npm.flatOptions }) + const data = await res.json() + let maxCurrent = '0.0.0' + let maxLTS = '0.0.0' + for (const { lts, version } of data) { + if (lts && semver.gt(version, maxLTS)) { + maxLTS = version } - const recommended = semver.gt(maxCurrent, maxLTS) ? maxCurrent : maxLTS - if (semver.gte(process.version, recommended)) { - return `current: ${current}, recommended: ${recommended}` - } else { - throw `Use node ${recommended} (current: ${current})` + + if (semver.satisfies(version, currentRange) && semver.gt(version, maxCurrent)) { + maxCurrent = version } - } finally { - tracker.finish() + } + const recommended = semver.gt(maxCurrent, maxLTS) ? maxCurrent : maxLTS + if (semver.gte(process.version, recommended)) { + return `current: ${current}, recommended: ${recommended}` + } else { + throw `Use node ${recommended} (current: ${current})` } } - async getBinPath (dir) { - const tracker = log.newItem('getBinPath', 1) - tracker.info('getBinPath', 'Finding npm global bin in your PATH') + async getBinPath () { + log.info('doctor', 'getBinPath', 'Finding npm global bin in your PATH') if (!process.env.PATH.includes(this.npm.globalBin)) { throw new Error(`Add ${this.npm.globalBin} to your $PATH`) } @@ -250,30 +218,25 @@ class Doctor extends BaseCommand { async checkFilesPermission (root, shouldOwn, mask, missingOk) { let ok = true - const tracker = log.newItem(root, 1) - try { const uid = process.getuid() const gid = process.getgid() const files = new Set([root]) for (const f of files) { - tracker.silly('checkFilesPermission', f.slice(root.length + 1)) const st = await lstat(f).catch(er => { // if it can't be missing, or if it can and the error wasn't that it was missing if (!missingOk || er.code !== 'ENOENT') { ok = false - tracker.warn('checkFilesPermission', 'error getting info for ' + f) + log.warn('doctor', 'checkFilesPermission', 'error getting info for ' + f) } }) - tracker.completeWork(1) - if (!st) { continue } if (shouldOwn && (uid !== st.uid || gid !== st.gid)) { - tracker.warn('checkFilesPermission', 'should be owner of ' + f) + log.warn('doctor', 'checkFilesPermission', 'should be owner of ' + f) ok = false } @@ -286,14 +249,14 @@ class Doctor extends BaseCommand { } catch (er) { ok = false const msg = `Missing permissions on ${f} (expect: ${maskLabel(mask)})` - tracker.error('checkFilesPermission', msg) + log.error('doctor', 'checkFilesPermission', msg) continue } if (st.isDirectory()) { - const entries = await readdir(f).catch(er => { + const entries = await readdir(f).catch(() => { ok = false - tracker.warn('checkFilesPermission', 'error reading directory ' + f) + log.warn('doctor', 'checkFilesPermission', 'error reading directory ' + f) return [] }) for (const entry of entries) { @@ -302,7 +265,6 @@ class Doctor extends BaseCommand { } } } finally { - tracker.finish() if (!ok) { throw ( `Check the permissions of files in ${root}` + @@ -315,50 +277,43 @@ class Doctor extends BaseCommand { } async getGitPath () { - const tracker = log.newItem('getGitPath', 1) - tracker.info('getGitPath', 'Finding git in your PATH') - try { - return await which('git').catch(er => { - tracker.warn(er) - throw new Error("Install git and ensure it's in your PATH.") - }) - } finally { - tracker.finish() - } + log.info('doctor', 'Finding git in your PATH') + return await which('git').catch(er => { + log.warn('doctor', 'getGitPath', er) + throw new Error("Install git and ensure it's in your PATH.") + }) } async verifyCachedFiles () { - const tracker = log.newItem('verifyCachedFiles', 1) - tracker.info('verifyCachedFiles', 'Verifying the npm cache') - try { - const stats = await cacache.verify(this.npm.flatOptions.cache) - const { badContentCount, reclaimedCount, missingContent, reclaimedSize } = stats - if (badContentCount || reclaimedCount || missingContent) { - if (badContentCount) { - tracker.warn('verifyCachedFiles', `Corrupted content removed: ${badContentCount}`) - } + log.info('doctor', 'verifyCachedFiles', 'Verifying the npm cache') - if (reclaimedCount) { - tracker.warn( - 'verifyCachedFiles', - `Content garbage-collected: ${reclaimedCount} (${reclaimedSize} bytes)` - ) - } + const stats = await cacache.verify(this.npm.flatOptions.cache) + const { badContentCount, reclaimedCount, missingContent, reclaimedSize } = stats + if (badContentCount || reclaimedCount || missingContent) { + if (badContentCount) { + log.warn('doctor', 'verifyCachedFiles', `Corrupted content removed: ${badContentCount}`) + } - if (missingContent) { - tracker.warn('verifyCachedFiles', `Missing content: ${missingContent}`) - } + if (reclaimedCount) { + log.warn( + 'doctor', + 'verifyCachedFiles', + `Content garbage-collected: ${reclaimedCount} (${reclaimedSize} bytes)` + ) + } - tracker.warn('verifyCachedFiles', 'Cache issues have been fixed') + if (missingContent) { + log.warn('doctor', 'verifyCachedFiles', `Missing content: ${missingContent}`) } - tracker.info( - 'verifyCachedFiles', - `Verification complete. Stats: ${JSON.stringify(stats, null, 2)}` - ) - return `verified ${stats.verifiedContent} tarballs` - } finally { - tracker.finish() + + log.warn('doctor', 'verifyCachedFiles', 'Cache issues have been fixed') } + log.info( + 'doctor', + 'verifyCachedFiles', + `Verification complete. Stats: ${JSON.stringify(stats, null, 2)}` + ) + return `verified ${stats.verifiedContent} tarballs` } async checkNpmRegistry () { @@ -369,38 +324,11 @@ class Doctor extends BaseCommand { } } - output (row) { - const t = new Table({ - chars: { - top: '', - 'top-mid': '', - 'top-left': '', - 'top-right': '', - bottom: '', - 'bottom-mid': '', - 'bottom-left': '', - 'bottom-right': '', - left: '', - 'left-mid': '', - mid: '', - 'mid-mid': '', - right: '', - 'right-mid': '', - middle: ' ', - }, - style: { - 'padding-left': 0, - 'padding-right': 0, - // setting border here is not necessary visually since we've already - // zeroed out all the chars above, but without it cli-table3 will wrap - // some of the separator spaces with ansi codes which show up in - // snapshots. - border: 0, - }, - colWidths: [this.#checkWidth, 6], - }) - t.push(row) - this.npm.output(t.toString()) + output (...args) { + // TODO display layer should do this + if (!this.npm.silent) { + output.standard(...args) + } } actions (params) { diff --git a/deps/npm/lib/commands/edit.js b/deps/npm/lib/commands/edit.js index fbc7840a39876f..4110a1db55e825 100644 --- a/deps/npm/lib/commands/edit.js +++ b/deps/npm/lib/commands/edit.js @@ -1,34 +1,31 @@ -// npm edit -// open the package folder in the $EDITOR - const { resolve } = require('path') -const fs = require('graceful-fs') +const { lstat } = require('fs/promises') const cp = require('child_process') -const completion = require('../utils/completion/installed-shallow.js') -const BaseCommand = require('../base-command.js') +const completion = require('../utils/installed-shallow.js') +const BaseCommand = require('../base-cmd.js') -const splitPackageNames = (path) => { - return path.split('/') - // combine scoped parts - .reduce((parts, part) => { - if (parts.length === 0) { - return [part] - } +const splitPackageNames = (path) => path.split('/') +// combine scoped parts + .reduce((parts, part) => { + if (parts.length === 0) { + return [part] + } - const lastPart = parts[parts.length - 1] - // check if previous part is the first part of a scoped package - if (lastPart[0] === '@' && !lastPart.includes('/')) { - parts[parts.length - 1] += '/' + part - } else { - parts.push(part) - } + const lastPart = parts[parts.length - 1] + // check if previous part is the first part of a scoped package + if (lastPart[0] === '@' && !lastPart.includes('/')) { + parts[parts.length - 1] += '/' + part + } else { + parts.push(part) + } - return parts - }, []) - .join('/node_modules/') - .replace(/(\/node_modules)+/, '/node_modules') -} + return parts + }, []) + .join('/node_modules/') + .replace(/(\/node_modules)+/, '/node_modules') +// npm edit +// open the package folder in the $EDITOR class Edit extends BaseCommand { static description = 'Edit an installed package' static name = 'edit' @@ -50,27 +47,18 @@ class Edit extends BaseCommand { const path = splitPackageNames(args[0]) const dir = resolve(this.npm.dir, path) - // graceful-fs does not promisify + await lstat(dir) await new Promise((res, rej) => { - fs.lstat(dir, (err) => { - if (err) { - return rej(err) + const [bin, ...spawnArgs] = this.npm.config.get('editor').split(/\s+/) + const editor = cp.spawn(bin, [...spawnArgs, dir], { stdio: 'inherit' }) + editor.on('exit', async (code) => { + if (code) { + return rej(new Error(`editor process exited with code: ${code}`)) } - const [bin, ...spawnArgs] = this.npm.config.get('editor').split(/\s+/) - const editor = cp.spawn(bin, [...spawnArgs, dir], { stdio: 'inherit' }) - editor.on('exit', async (code) => { - if (code) { - return rej(new Error(`editor process exited with code: ${code}`)) - } - try { - await this.npm.exec('rebuild', [dir]) - } catch (execErr) { - rej(execErr) - } - res() - }) + await this.npm.exec('rebuild', [dir]).then(res).catch(rej) }) }) } } + module.exports = Edit diff --git a/deps/npm/lib/commands/exec.js b/deps/npm/lib/commands/exec.js index d532eca107c6c1..9bb4b15e0c5a3c 100644 --- a/deps/npm/lib/commands/exec.js +++ b/deps/npm/lib/commands/exec.js @@ -1,6 +1,6 @@ const { resolve } = require('path') const libexec = require('libnpmexec') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') class Exec extends BaseCommand { static description = 'Run a command from a local or remote npm package' @@ -65,7 +65,6 @@ class Exec extends BaseCommand { globalDir, chalk, } = this.npm - const output = this.npm.output.bind(this.npm) const scriptShell = this.npm.config.get('script-shell') || undefined const packages = this.npm.config.get('package') const yes = this.npm.config.get('yes') @@ -93,7 +92,6 @@ class Exec extends BaseCommand { globalPath, localBin, locationMsg, - output, packages, path, runPath, diff --git a/deps/npm/lib/commands/explain.js b/deps/npm/lib/commands/explain.js index 403274db68dfaf..2e7d07df729a8c 100644 --- a/deps/npm/lib/commands/explain.js +++ b/deps/npm/lib/commands/explain.js @@ -3,6 +3,7 @@ const npa = require('npm-package-arg') const semver = require('semver') const { relative, resolve } = require('path') const validName = require('validate-npm-package-name') +const { output } = require('proc-log') const ArboristWorkspaceCmd = require('../arborist-cmd.js') class Explain extends ArboristWorkspaceCmd { @@ -19,7 +20,7 @@ class Explain extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ static async completion (opts, npm) { - const completion = require('../utils/completion/installed-deep.js') + const completion = require('../utils/installed-deep.js') return completion(npm, opts) } @@ -75,9 +76,9 @@ class Explain extends ArboristWorkspaceCmd { } if (this.npm.flatOptions.json) { - this.npm.output(JSON.stringify(expls, null, 2)) + output.standard(JSON.stringify(expls, null, 2)) } else { - this.npm.output(expls.map(expl => { + output.standard(expls.map(expl => { return explainNode(expl, Infinity, this.npm.chalk) }).join('\n\n')) } @@ -125,4 +126,5 @@ class Explain extends ArboristWorkspaceCmd { }) } } + module.exports = Explain diff --git a/deps/npm/lib/commands/explore.js b/deps/npm/lib/commands/explore.js index 7a03ea4eabd7f6..d9dd9a9931f569 100644 --- a/deps/npm/lib/commands/explore.js +++ b/deps/npm/lib/commands/explore.js @@ -1,13 +1,12 @@ -// npm explore [@] -// open a subshell to the package folder. - const pkgJson = require('@npmcli/package-json') const runScript = require('@npmcli/run-script') const { join, relative } = require('path') -const log = require('../utils/log-shim.js') -const completion = require('../utils/completion/installed-shallow.js') -const BaseCommand = require('../base-command.js') +const { log, output } = require('proc-log') +const completion = require('../utils/installed-shallow.js') +const BaseCommand = require('../base-cmd.js') +// npm explore [@] +// open a subshell to the package folder. class Explore extends BaseCommand { static description = 'Browse an installed package' static name = 'explore' @@ -50,30 +49,26 @@ class Explore extends BaseCommand { } if (!args.length) { - this.npm.output(`\nExploring ${path}\nType 'exit' or ^D when finished\n`) + output.standard(`\nExploring ${path}\nType 'exit' or ^D when finished\n`) } - log.disableProgress() - try { - return await runScript({ - ...this.npm.flatOptions, - pkg, - banner: false, - path, - event: '_explore', - stdio: 'inherit', - }).catch(er => { - process.exitCode = typeof er.code === 'number' && er.code !== 0 ? er.code - : 1 + + return runScript({ + ...this.npm.flatOptions, + pkg, + path, + event: '_explore', + stdio: 'inherit', + }).catch(er => { + process.exitCode = typeof er.code === 'number' && er.code !== 0 ? er.code + : 1 // if it's not an exit error, or non-interactive, throw it - const isProcExit = er.message === 'command failed' && + const isProcExit = er.message === 'command failed' && (typeof er.code === 'number' || /^SIG/.test(er.signal || '')) - if (args.length || !isProcExit) { - throw er - } - }) - } finally { - log.enableProgress() - } + if (args.length || !isProcExit) { + throw er + } + }) } } + module.exports = Explore diff --git a/deps/npm/lib/commands/find-dupes.js b/deps/npm/lib/commands/find-dupes.js index 2e06e8b6bd93f4..735ac7c4a7ed09 100644 --- a/deps/npm/lib/commands/find-dupes.js +++ b/deps/npm/lib/commands/find-dupes.js @@ -1,6 +1,6 @@ -// dedupe duplicated packages, or find them in the tree const ArboristWorkspaceCmd = require('../arborist-cmd.js') +// dedupe duplicated packages, or find them in the tree class FindDupes extends ArboristWorkspaceCmd { static description = 'Find duplication in the package tree' static name = 'find-dupes' @@ -19,9 +19,10 @@ class FindDupes extends ArboristWorkspaceCmd { ...super.params, ] - async exec (args) { + async exec () { this.npm.config.set('dry-run', true) return this.npm.exec('dedupe', []) } } + module.exports = FindDupes diff --git a/deps/npm/lib/commands/fund.js b/deps/npm/lib/commands/fund.js index 2804d36cd56034..8bcd184e709683 100644 --- a/deps/npm/lib/commands/fund.js +++ b/deps/npm/lib/commands/fund.js @@ -1,6 +1,7 @@ const archy = require('archy') const pacote = require('pacote') const semver = require('semver') +const { output } = require('proc-log') const npa = require('npm-package-arg') const { depth } = require('treeverse') const { readTree: getFundingInfo, normalizeFunding, isValidFunding } = require('libnpmfund') @@ -37,7 +38,7 @@ class Fund extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ static async completion (opts, npm) { - const completion = require('../utils/completion/installed-deep.js') + const completion = require('../utils/installed-deep.js') return completion(npm, opts) } @@ -85,9 +86,9 @@ class Fund extends ArboristWorkspaceCmd { }) if (this.npm.config.get('json')) { - this.npm.output(this.printJSON(fundingInfo)) + output.standard(this.printJSON(fundingInfo)) } else { - this.npm.output(this.printHuman(fundingInfo)) + output.standard(this.printHuman(fundingInfo)) } } @@ -110,26 +111,25 @@ class Fund extends ArboristWorkspaceCmd { const [fundingSource] = [].concat(normalizeFunding(funding)).filter(isValidFunding) const { url } = fundingSource || {} const pkgRef = getPrintableName({ name, version }) - let item = { - label: pkgRef, - } - if (url) { - item.label = tree({ - label: this.npm.chalk.bgBlack.white(url), + if (!url) { + return { label: pkgRef } + } + let item + if (seenUrls.has(url)) { + item = seenUrls.get(url) + item.label += `${this.npm.chalk.dim(',')} ${pkgRef}` + return null + } + item = { + label: tree({ + label: this.npm.chalk.blue(url), nodes: [pkgRef], - }).trim() - - // stacks all packages together under the same item - if (seenUrls.has(url)) { - item = seenUrls.get(url) - item.label += `, ${pkgRef}` - return null - } else { - seenUrls.set(url, item) - } + }).trim(), } + // stacks all packages together under the same item + seenUrls.set(url, item) return item }, @@ -153,7 +153,7 @@ class Fund extends ArboristWorkspaceCmd { }) const res = tree(result) - return this.npm.chalk.reset(res) + return res } async openFundingUrl ({ path, tree, spec, fundingSourceNumber }) { @@ -212,7 +212,7 @@ class Fund extends ArboristWorkspaceCmd { if (fundingSourceNumber) { ambiguousUrlMsg.unshift(`--which=${fundingSourceNumber} is not a valid index`) } - this.npm.output(ambiguousUrlMsg.join('\n')) + output.standard(ambiguousUrlMsg.join('\n')) } urlMessage (source) { @@ -222,4 +222,5 @@ class Fund extends ArboristWorkspaceCmd { return [url, message] } } + module.exports = Fund diff --git a/deps/npm/lib/commands/get.js b/deps/npm/lib/commands/get.js index 4bf5d2caf82645..4191f2c973e7d3 100644 --- a/deps/npm/lib/commands/get.js +++ b/deps/npm/lib/commands/get.js @@ -1,5 +1,5 @@ const Npm = require('../npm.js') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') class Get extends BaseCommand { static description = 'Get a value from the npm configuration' @@ -19,4 +19,5 @@ class Get extends BaseCommand { return this.npm.exec('config', ['get'].concat(args)) } } + module.exports = Get diff --git a/deps/npm/lib/commands/help-search.js b/deps/npm/lib/commands/help-search.js index 273807c7469af0..72dd03ac7406ec 100644 --- a/deps/npm/lib/commands/help-search.js +++ b/deps/npm/lib/commands/help-search.js @@ -1,7 +1,8 @@ -const { readFile } = require('fs/promises') -const path = require('path') +const { readFile } = require('node:fs/promises') +const path = require('node:path') const { glob } = require('glob') -const BaseCommand = require('../base-command.js') +const { output } = require('proc-log') +const BaseCommand = require('../base-cmd.js') const globify = pattern => pattern.split('\\').join('/') @@ -21,12 +22,12 @@ class HelpSearch extends BaseCommand { // preserve glob@8 behavior files = files.sort((a, b) => a.localeCompare(b, 'en')) const data = await this.readFiles(files) - const results = await this.searchFiles(args, data, files) + const results = await this.searchFiles(args, data) const formatted = this.formatResults(args, results) if (!formatted.trim()) { - this.npm.output(`No matches in help for: ${args.join(' ')}\n`) + output.standard(`No matches in help for: ${args.join(' ')}\n`) } else { - this.npm.output(formatted) + output.standard(formatted) } } @@ -39,7 +40,7 @@ class HelpSearch extends BaseCommand { return res } - async searchFiles (args, data, files) { + async searchFiles (args, data) { const results = [] for (const [file, content] of Object.entries(data)) { const lowerCase = content.toLowerCase() @@ -140,7 +141,7 @@ class HelpSearch extends BaseCommand { formatResults (args, results) { const cols = Math.min(process.stdout.columns || Infinity, 80) + 1 - const output = results.map(res => { + const formattedOutput = results.map(res => { const out = [res.cmd] const r = Object.keys(res.hits) .map(k => `${k}:${res.hits[k]}`) @@ -169,8 +170,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 = this.npm.chalk.bgBlack.red(word) - hilitLine.push(hilit) + hilitLine.push(this.npm.chalk.blue(word)) p += f.length + arg.length } } @@ -183,12 +183,13 @@ class HelpSearch extends BaseCommand { const finalOut = results.length && !this.npm.config.get('long') ? 'Top hits for ' + (args.map(JSON.stringify).join(' ')) + '\n' + '—'.repeat(cols - 1) + '\n' + - output + '\n' + + formattedOutput + '\n' + '—'.repeat(cols - 1) + '\n' + '(run with -l or --long to see more context)' - : output + : formattedOutput return finalOut.trim() } } + module.exports = HelpSearch diff --git a/deps/npm/lib/commands/help.js b/deps/npm/lib/commands/help.js index 39c580f9a68715..fb3fe664e017df 100644 --- a/deps/npm/lib/commands/help.js +++ b/deps/npm/lib/commands/help.js @@ -2,11 +2,12 @@ const spawn = require('@npmcli/promise-spawn') const path = require('path') const openUrl = require('../utils/open-url.js') const { glob } = require('glob') +const { output } = require('proc-log') const localeCompare = require('@isaacs/string-locale-compare')('en') const { deref } = require('../utils/cmd-list.js') +const BaseCommand = require('../base-cmd.js') 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 // We don't currently compress our man pages but if we ever did this would @@ -50,7 +51,7 @@ class Help extends BaseCommand { const manSearch = /^\d+$/.test(args[0]) ? `man${args.shift()}` : 'man*' if (!args.length) { - return this.npm.output(this.npm.usage) + return output.standard(this.npm.usage) } // npm help foo bar baz: search topics @@ -110,4 +111,5 @@ class Help extends BaseCommand { return 'file:///' + path.resolve(this.npm.npmRoot, `docs/output/${sect}/${f}.html`) } } + module.exports = Help diff --git a/deps/npm/lib/commands/hook.js b/deps/npm/lib/commands/hook.js index b0f52a801f5717..3b91ff539081a9 100644 --- a/deps/npm/lib/commands/hook.js +++ b/deps/npm/lib/commands/hook.js @@ -1,9 +1,9 @@ const hookApi = require('libnpmhook') const otplease = require('../utils/otplease.js') const relativeDate = require('tiny-relative-date') -const Table = require('cli-table3') +const { output } = require('proc-log') +const BaseCommand = require('../base-cmd.js') -const BaseCommand = require('../base-command.js') class Hook extends BaseCommand { static description = 'Manage registry hooks' static name = 'hook' @@ -40,86 +40,70 @@ class Hook extends BaseCommand { async add (pkg, uri, secret, opts) { const hook = await hookApi.add(pkg, uri, secret, opts) if (opts.json) { - this.npm.output(JSON.stringify(hook, null, 2)) + output.standard(JSON.stringify(hook, null, 2)) } else if (opts.parseable) { - this.npm.output(Object.keys(hook).join('\t')) - this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) + output.standard(Object.keys(hook).join('\t')) + output.standard(Object.keys(hook).map(k => hook[k]).join('\t')) } else if (!this.npm.silent) { - this.npm.output(`+ ${this.hookName(hook)} ${opts.unicode ? ' ➜ ' : ' -> '} ${hook.endpoint}`) + output.standard(`+ ${this.hookName(hook)} ${opts.unicode ? ' ➜ ' : ' -> '} ${hook.endpoint}`) } } async ls (pkg, opts) { const hooks = await hookApi.ls({ ...opts, package: pkg }) + if (opts.json) { - this.npm.output(JSON.stringify(hooks, null, 2)) + output.standard(JSON.stringify(hooks, null, 2)) } else if (opts.parseable) { - this.npm.output(Object.keys(hooks[0]).join('\t')) + output.standard(Object.keys(hooks[0]).join('\t')) hooks.forEach(hook => { - this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) + output.standard(Object.keys(hook).map(k => hook[k]).join('\t')) }) } else if (!hooks.length) { - this.npm.output("You don't have any hooks configured yet.") + output.standard("You don't have any hooks configured yet.") } else if (!this.npm.silent) { - if (hooks.length === 1) { - this.npm.output('You have one hook configured.') - } else { - this.npm.output(`You have ${hooks.length} hooks configured.`) - } + output.standard(`You have ${hooks.length} hook${hooks.length !== 1 ? 's' : ''} configured.`) - const table = new Table({ head: ['id', 'target', 'endpoint'] }) - hooks.forEach((hook) => { - table.push([ - { rowSpan: 2, content: hook.id }, - this.hookName(hook), - hook.endpoint, - ]) + for (const hook of hooks) { + output.standard(`Hook ${hook.id}: ${this.hookName(hook)}`) + output.standard(`Endpoint: ${hook.endpoint}`) if (hook.last_delivery) { - table.push([ - { - colSpan: 1, - content: `triggered ${relativeDate(hook.last_delivery)}`, - }, - hook.response_code, - ]) + /* eslint-disable-next-line max-len */ + output.standard(`Triggered ${relativeDate(hook.last_delivery)}, response code was "${hook.response_code}"\n`) } else { - table.push([{ colSpan: 2, content: 'never triggered' }]) + output.standard('Never triggered\n') } - }) - this.npm.output(table.toString()) + } } } async rm (id, opts) { const hook = await hookApi.rm(id, opts) if (opts.json) { - this.npm.output(JSON.stringify(hook, null, 2)) + output.standard(JSON.stringify(hook, null, 2)) } else if (opts.parseable) { - this.npm.output(Object.keys(hook).join('\t')) - this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) + output.standard(Object.keys(hook).join('\t')) + output.standard(Object.keys(hook).map(k => hook[k]).join('\t')) } else if (!this.npm.silent) { - this.npm.output(`- ${this.hookName(hook)} ${opts.unicode ? ' ✘ ' : ' X '} ${hook.endpoint}`) + output.standard(`- ${this.hookName(hook)} ${opts.unicode ? ' ✘ ' : ' X '} ${hook.endpoint}`) } } async update (id, uri, secret, opts) { const hook = await hookApi.update(id, uri, secret, opts) if (opts.json) { - this.npm.output(JSON.stringify(hook, null, 2)) + output.standard(JSON.stringify(hook, null, 2)) } else if (opts.parseable) { - this.npm.output(Object.keys(hook).join('\t')) - this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) + output.standard(Object.keys(hook).join('\t')) + output.standard(Object.keys(hook).map(k => hook[k]).join('\t')) } else if (!this.npm.silent) { - this.npm.output(`+ ${this.hookName(hook)} ${opts.unicode ? ' ➜ ' : ' -> '} ${hook.endpoint}`) + output.standard(`+ ${this.hookName(hook)} ${opts.unicode ? ' ➜ ' : ' -> '} ${hook.endpoint}`) } } hookName (hook) { - let target = hook.name - if (hook.type === 'owner') { - target = '~' + target - } - return target + return `${hook.type === 'owner' ? '~' : ''}${hook.name}` } } + module.exports = Hook diff --git a/deps/npm/lib/commands/init.js b/deps/npm/lib/commands/init.js index 030c97356edb83..205352e86e6edc 100644 --- a/deps/npm/lib/commands/init.js +++ b/deps/npm/lib/commands/init.js @@ -1,4 +1,4 @@ -const fs = require('fs') +const { statSync } = require('fs') const { relative, resolve } = require('path') const { mkdir } = require('fs/promises') const initJson = require('init-package-json') @@ -6,13 +6,12 @@ const npa = require('npm-package-arg') const libexec = require('libnpmexec') const mapWorkspaces = require('@npmcli/map-workspaces') const PackageJson = require('@npmcli/package-json') -const log = require('../utils/log-shim.js') -const updateWorkspaces = require('../workspaces/update-workspaces.js') +const { log, output, input } = require('proc-log') +const updateWorkspaces = require('../utils/update-workspaces.js') +const BaseCommand = require('../base-cmd.js') const posixPath = p => p.split('\\').join('/') -const BaseCommand = require('../base-command.js') - class Init extends BaseCommand { static description = 'Create a package.json file' static params = [ @@ -60,7 +59,7 @@ class Init extends BaseCommand { // to create a workspace package.json file or its folders const { content: pkg } = await PackageJson.normalize(this.npm.localPrefix).catch(err => { if (err.code === 'ENOENT') { - log.warn('Missing package.json. Try with `--include-workspace-root`.') + log.warn('init', 'Missing package.json. Try with `--include-workspace-root`.') } throw err }) @@ -130,7 +129,6 @@ class Init extends BaseCommand { globalBin, chalk, } = this.npm - const output = this.npm.output.bind(this.npm) const runPath = path const scriptShell = this.npm.config.get('script-shell') || undefined const yes = this.npm.config.get('yes') @@ -150,12 +148,9 @@ class Init extends BaseCommand { } async template (path = process.cwd()) { - log.pause() - log.disableProgress() - const initFile = this.npm.config.get('init-module') if (!this.npm.config.get('yes') && !this.npm.config.get('force')) { - this.npm.output([ + output.standard([ 'This utility will walk you through creating a package.json file.', 'It only covers the most common items, and tries to guess sensible defaults.', '', @@ -170,7 +165,7 @@ class Init extends BaseCommand { } try { - const data = await initJson(path, initFile, this.npm.config) + const data = await input.read(() => initJson(path, initFile, this.npm.config)) log.silly('package data', data) return data } catch (er) { @@ -179,9 +174,6 @@ class Init extends BaseCommand { } else { throw er } - } finally { - log.resume() - log.enableProgress() } } @@ -200,7 +192,7 @@ class Init extends BaseCommand { // mapWorkspaces, so we're just going to avoid touching the // top-level package.json try { - fs.statSync(resolve(workspacePath, 'package.json')) + statSync(resolve(workspacePath, 'package.json')) } catch (err) { return } diff --git a/deps/npm/lib/commands/install-ci-test.js b/deps/npm/lib/commands/install-ci-test.js index f7a357ba6e1246..4b9dd269f8c748 100644 --- a/deps/npm/lib/commands/install-ci-test.js +++ b/deps/npm/lib/commands/install-ci-test.js @@ -1,8 +1,7 @@ -// npm install-ci-test -// Runs `npm ci` and then runs `npm test` - const CI = require('./ci.js') +// npm install-ci-test +// Runs `npm ci` and then runs `npm test` class InstallCITest extends CI { static description = 'Install a project with a clean slate and run tests' static name = 'install-ci-test' @@ -12,4 +11,5 @@ class InstallCITest extends CI { return this.npm.exec('test', []) } } + module.exports = InstallCITest diff --git a/deps/npm/lib/commands/install-test.js b/deps/npm/lib/commands/install-test.js index 11f22e535403cc..e21ca7c929c55e 100644 --- a/deps/npm/lib/commands/install-test.js +++ b/deps/npm/lib/commands/install-test.js @@ -1,8 +1,7 @@ -// npm install-test -// Runs `npm install` and then runs `npm test` - const Install = require('./install.js') +// npm install-test +// Runs `npm install` and then runs `npm test` class InstallTest extends Install { static description = 'Install package(s) and run tests' static name = 'install-test' @@ -12,4 +11,5 @@ class InstallTest extends Install { return this.npm.exec('test', []) } } + module.exports = InstallTest diff --git a/deps/npm/lib/commands/install.js b/deps/npm/lib/commands/install.js index d04a35fbec2a76..24e5f6819b3141 100644 --- a/deps/npm/lib/commands/install.js +++ b/deps/npm/lib/commands/install.js @@ -1,15 +1,12 @@ -/* eslint-disable camelcase */ -const fs = require('fs') -const util = require('util') -const readdir = util.promisify(fs.readdir) -const reifyFinish = require('../utils/reify-finish.js') -const log = require('../utils/log-shim.js') -const { resolve, join } = require('path') +const { readdir } = require('node:fs/promises') +const { resolve, join } = require('node:path') +const { log } = require('proc-log') const runScript = require('@npmcli/run-script') const pacote = require('pacote') const checks = require('npm-install-checks') - +const reifyFinish = require('../utils/reify-finish.js') const ArboristWorkspaceCmd = require('../arborist-cmd.js') + class Install extends ArboristWorkspaceCmd { static description = 'Install a package' static name = 'install' @@ -168,7 +165,6 @@ class Install extends ArboristWorkspaceCmd { args: [], scriptShell, stdio: 'inherit', - banner: !this.npm.silent, event, }) } @@ -176,4 +172,5 @@ class Install extends ArboristWorkspaceCmd { await reifyFinish(this.npm, arb) } } + module.exports = Install diff --git a/deps/npm/lib/commands/link.js b/deps/npm/lib/commands/link.js index cdc248569849c3..bde761c4226dcd 100644 --- a/deps/npm/lib/commands/link.js +++ b/deps/npm/lib/commands/link.js @@ -1,15 +1,11 @@ -const fs = require('fs') -const util = require('util') -const readdir = util.promisify(fs.readdir) +const { readdir } = require('fs/promises') const { resolve } = require('path') - const npa = require('npm-package-arg') const pkgJson = require('@npmcli/package-json') const semver = require('semver') - const reifyFinish = require('../utils/reify-finish.js') - const ArboristWorkspaceCmd = require('../arborist-cmd.js') + class Link extends ArboristWorkspaceCmd { static description = 'Symlink a package folder' static name = 'link' @@ -189,4 +185,5 @@ class Link extends ArboristWorkspaceCmd { return missing } } + module.exports = Link diff --git a/deps/npm/lib/commands/login.js b/deps/npm/lib/commands/login.js index b498a3bf2ecd8b..630abf9ac8e045 100644 --- a/deps/npm/lib/commands/login.js +++ b/deps/npm/lib/commands/login.js @@ -1,8 +1,7 @@ -const log = require('../utils/log-shim.js') +const { log, output } = require('proc-log') const { redactLog: replaceInfo } = require('@npmcli/redact') const auth = require('../utils/auth.js') - -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') class Login extends BaseCommand { static description = 'Login to a registry user account' @@ -13,7 +12,7 @@ class Login extends BaseCommand { 'auth-type', ] - async exec (args) { + async exec () { const scope = this.npm.config.get('scope') let registry = this.npm.config.get('registry') @@ -27,7 +26,6 @@ class Login extends BaseCommand { const creds = this.npm.config.getCredentialsByURI(registry) - log.disableProgress() log.notice('', `Log in on ${replaceInfo(registry)}`) const { message, newCreds } = await auth.login(this.npm, { @@ -45,7 +43,8 @@ class Login extends BaseCommand { await this.npm.config.save('user') - this.npm.output(message) + output.standard(message) } } + module.exports = Login diff --git a/deps/npm/lib/commands/logout.js b/deps/npm/lib/commands/logout.js index 665580930639cf..dc5a0dfda0e98e 100644 --- a/deps/npm/lib/commands/logout.js +++ b/deps/npm/lib/commands/logout.js @@ -1,7 +1,7 @@ const npmFetch = require('npm-registry-fetch') const { getAuth } = npmFetch -const log = require('../utils/log-shim') -const BaseCommand = require('../base-command.js') +const { log } = require('proc-log') +const BaseCommand = require('../base-cmd.js') class Logout extends BaseCommand { static description = 'Log out of the registry' @@ -11,7 +11,7 @@ class Logout extends BaseCommand { 'scope', ] - async exec (args) { + async exec () { const registry = this.npm.config.get('registry') const scope = this.npm.config.get('scope') const regRef = scope ? `${scope}:registry` : 'registry' @@ -46,4 +46,5 @@ class Logout extends BaseCommand { await this.npm.config.save(level) } } + module.exports = Logout diff --git a/deps/npm/lib/commands/ls.js b/deps/npm/lib/commands/ls.js index 3f9775cf125040..51e99f429816a9 100644 --- a/deps/npm/lib/commands/ls.js +++ b/deps/npm/lib/commands/ls.js @@ -1,10 +1,12 @@ const { resolve, relative, sep } = require('path') -const relativePrefix = `.${sep}` -const { EOL } = require('os') - const archy = require('archy') const { breadth } = require('treeverse') const npa = require('npm-package-arg') +const { output } = require('proc-log') +const ArboristWorkspaceCmd = require('../arborist-cmd.js') +const localeCompare = require('@isaacs/string-locale-compare')('en') + +const relativePrefix = `.${sep}` const _depth = Symbol('depth') const _dedupe = Symbol('dedupe') @@ -17,8 +19,6 @@ const _parent = Symbol('parent') const _problems = Symbol('problems') const _required = Symbol('required') const _type = Symbol('type') -const ArboristWorkspaceCmd = require('../arborist-cmd.js') -const localeCompare = require('@isaacs/string-locale-compare')('en') class LS extends ArboristWorkspaceCmd { static description = 'List installed packages' @@ -42,7 +42,7 @@ class LS extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ static async completion (opts, npm) { - const completion = require('../utils/completion/installed-deep.js') + const completion = require('../utils/installed-deep.js') return completion(npm, opts) } @@ -177,7 +177,7 @@ class LS extends ArboristWorkspaceCmd { const [rootError] = tree.errors.filter(e => e.code === 'EJSONPARSE' && e.path === resolve(path, 'package.json')) - this.npm.outputBuffer( + output.buffer( json ? jsonOutput({ path, problems, result, rootError, seenItems }) : parseable ? parseableOutput({ seenNodes, global, long }) : humanOutput({ chalk, result, seenItems, unicode }) @@ -200,7 +200,7 @@ class LS extends ArboristWorkspaceCmd { if (shouldThrow) { throw Object.assign( - new Error([...problems].join(EOL)), + new Error([...problems].join('\n')), { code: 'ELSPROBLEMS' } ) } @@ -219,6 +219,7 @@ class LS extends ArboristWorkspaceCmd { return tree } } + module.exports = LS const isGitNode = (node) => { @@ -280,7 +281,7 @@ const augmentItemWithIncludeMetadata = (node, item) => { const getHumanOutputItem = (node, { args, chalk, global, long }) => { const { pkgid, path } = node - const workspacePkgId = chalk.green(pkgid) + const workspacePkgId = chalk.blueBright(pkgid) let printable = node.isWorkspace ? workspacePkgId : pkgid // special formatting for top-level package name @@ -289,14 +290,16 @@ const getHumanOutputItem = (node, { args, chalk, global, long }) => { if (hasNoPackageJson || global) { printable = path } else { - printable += `${long ? EOL : ' '}${path}` + printable += `${long ? '\n' : ' '}${path}` } } + // TODO there is a LOT of overlap with lib/utils/explain-dep.js here + const highlightDepName = args.length && node[_filteredBy] const missingColor = isOptional(node) - ? chalk.yellow.bgBlack - : chalk.red.bgBlack + ? chalk.yellow + : chalk.red const missingMsg = `UNMET ${isOptional(node) ? 'OPTIONAL ' : ''}DEPENDENCY` const targetLocation = node.root ? relative(node.root.realpath, node.realpath) @@ -310,30 +313,30 @@ const getHumanOutputItem = (node, { args, chalk, global, long }) => { ? missingColor(missingMsg) + ' ' : '' ) + - `${highlightDepName ? chalk.yellow.bgBlack(printable) : printable}` + + `${highlightDepName ? chalk.yellow(printable) : printable}` + ( node[_dedupe] - ? ' ' + chalk.gray('deduped') + ? ' ' + chalk.dim('deduped') : '' ) + ( invalid - ? ' ' + chalk.red.bgBlack(invalid) + ? ' ' + chalk.red(invalid) : '' ) + ( isExtraneous(node, { global }) - ? ' ' + chalk.green.bgBlack('extraneous') + ? ' ' + chalk.red('extraneous') : '' ) + ( node.overridden - ? ' ' + chalk.gray('overridden') + ? ' ' + chalk.dim('overridden') : '' ) + (isGitNode(node) ? ` (${node.resolved})` : '') + (node.isLink ? ` -> ${relativePrefix}${targetLocation}` : '') + - (long ? `${EOL}${node.package.description || ''}` : '') + (long ? `\n${node.package.description || ''}` : '') return augmentItemWithIncludeMetadata(node, { label, nodes: [] }) } @@ -566,7 +569,7 @@ const parseableOutput = ({ global, long, seenNodes }) => { out += node[_invalid] ? ':INVALID' : '' out += node.overridden ? ':OVERRIDDEN' : '' } - out += EOL + out += '\n' } } return out.trim() diff --git a/deps/npm/lib/commands/org.js b/deps/npm/lib/commands/org.js index 1f32d41ff73068..af67547a643db2 100644 --- a/deps/npm/lib/commands/org.js +++ b/deps/npm/lib/commands/org.js @@ -1,7 +1,7 @@ const liborg = require('libnpmorg') const otplease = require('../utils/otplease.js') -const Table = require('cli-table3') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') +const { output } = require('proc-log') class Org extends BaseCommand { static description = 'Manage orgs' @@ -68,14 +68,14 @@ class Org extends BaseCommand { const memDeets = await liborg.set(org, user, role, opts) if (opts.json) { - this.npm.output(JSON.stringify(memDeets, null, 2)) + output.standard(JSON.stringify(memDeets, null, 2)) } else if (opts.parseable) { - this.npm.output(['org', 'orgsize', 'user', 'role'].join('\t')) - this.npm.output( + output.standard(['org', 'orgsize', 'user', 'role'].join('\t')) + output.standard( [memDeets.org.name, memDeets.org.size, memDeets.user, memDeets.role].join('\t') ) } else if (!this.npm.silent) { - this.npm.output( + output.standard( `Added ${memDeets.user} as ${memDeets.role} to ${memDeets.org.name}. You now have ${ memDeets.org.size } member${memDeets.org.size === 1 ? '' : 's'} in this org.` @@ -100,7 +100,7 @@ class Org extends BaseCommand { org = org.replace(/^[~@]?/, '') const userCount = Object.keys(roster).length if (opts.json) { - this.npm.output( + output.standard( JSON.stringify({ user, org, @@ -109,10 +109,10 @@ class Org extends BaseCommand { }) ) } else if (opts.parseable) { - this.npm.output(['user', 'org', 'userCount', 'deleted'].join('\t')) - this.npm.output([user, org, userCount, true].join('\t')) + output.standard(['user', 'org', 'userCount', 'deleted'].join('\t')) + output.standard([user, org, userCount, true].join('\t')) } else if (!this.npm.silent) { - this.npm.output( + output.standard( `Successfully removed ${user} from ${org}. You now have ${userCount} member${ userCount === 1 ? '' : 's' } in this org.` @@ -135,21 +135,19 @@ class Org extends BaseCommand { roster = newRoster } if (opts.json) { - this.npm.output(JSON.stringify(roster, null, 2)) + output.standard(JSON.stringify(roster, null, 2)) } else if (opts.parseable) { - this.npm.output(['user', 'role'].join('\t')) + output.standard(['user', 'role'].join('\t')) Object.keys(roster).forEach(u => { - this.npm.output([u, roster[u]].join('\t')) + output.standard([u, roster[u]].join('\t')) }) } else if (!this.npm.silent) { - const table = new Table({ head: ['user', 'role'] }) - Object.keys(roster) - .sort() - .forEach(u => { - table.push([u, roster[u]]) - }) - this.npm.output(table.toString()) + const chalk = this.npm.chalk + for (const u of Object.keys(roster).sort()) { + output.standard(`${u} - ${chalk.cyan(roster[u])}`) + } } } } + module.exports = Org diff --git a/deps/npm/lib/commands/outdated.js b/deps/npm/lib/commands/outdated.js index 4216f1cdb1437f..2249808110bbbf 100644 --- a/deps/npm/lib/commands/outdated.js +++ b/deps/npm/lib/commands/outdated.js @@ -1,12 +1,11 @@ -const os = require('node:os') const { resolve } = require('node:path') const { stripVTControlCharacters } = require('node:util') const pacote = require('pacote') const table = require('text-table') const npa = require('npm-package-arg') const pickManifest = require('npm-pick-manifest') +const { output } = require('proc-log') const localeCompare = require('@isaacs/string-locale-compare')('en') - const ArboristWorkspaceCmd = require('../arborist-cmd.js') class Outdated extends ArboristWorkspaceCmd { @@ -84,9 +83,9 @@ class Outdated extends ArboristWorkspaceCmd { // display results if (this.npm.config.get('json')) { - this.npm.output(this.makeJSON(outdated)) + output.standard(this.makeJSON(outdated)) } else if (this.npm.config.get('parseable')) { - this.npm.output(this.makeParseable(outdated)) + output.standard(this.makeParseable(outdated)) } else { const outList = outdated.map(x => this.makePretty(x)) const outHead = ['Package', @@ -102,13 +101,13 @@ class Outdated extends ArboristWorkspaceCmd { } const outTable = [outHead].concat(outList) - outTable[0] = outTable[0].map(heading => this.npm.chalk.underline(heading)) + outTable[0] = outTable[0].map(heading => this.npm.chalk.bold.underline(heading)) const tableOpts = { align: ['l', 'r', 'r', 'r', 'l'], stringLength: s => stripVTControlCharacters(s).length, } - this.npm.output(table(outTable, tableOpts)) + output.standard(table(outTable, tableOpts)) } } @@ -161,7 +160,7 @@ class Outdated extends ArboristWorkspaceCmd { this.edges.add(edge) } - getWorkspacesEdges (node) { + getWorkspacesEdges () { if (this.npm.global) { return } @@ -278,7 +277,7 @@ class Outdated extends ArboristWorkspaceCmd { : node.name return humanOutput - ? this.npm.chalk.green(workspaceName) + ? this.npm.chalk.blue(workspaceName) : workspaceName } @@ -295,17 +294,20 @@ class Outdated extends ArboristWorkspaceCmd { dependent, } = dep - const columns = [name, current, wanted, latest, location, dependent] + const columns = [ + this.npm.chalk[current === wanted ? 'yellow' : 'red'](name), + current, + this.npm.chalk.cyan(wanted), + this.npm.chalk.blue(latest), + location, + dependent, + ] if (this.npm.config.get('long')) { columns[6] = type - columns[7] = homepage + columns[7] = this.npm.chalk.blue(homepage) } - columns[0] = this.npm.chalk[current === wanted ? 'yellow' : 'red'](columns[0]) // current - columns[2] = this.npm.chalk.green(columns[2]) // wanted - columns[3] = this.npm.chalk.magenta(columns[3]) // latest - return columns } @@ -335,7 +337,7 @@ class Outdated extends ArboristWorkspaceCmd { } return out.join(':') - }).join(os.EOL) + }).join('\n') } makeJSON (list) { @@ -366,4 +368,5 @@ class Outdated extends ArboristWorkspaceCmd { return JSON.stringify(out, null, 2) } } + module.exports = Outdated diff --git a/deps/npm/lib/commands/owner.js b/deps/npm/lib/commands/owner.js index e530e1c51c8e1f..188065583198d0 100644 --- a/deps/npm/lib/commands/owner.js +++ b/deps/npm/lib/commands/owner.js @@ -1,10 +1,10 @@ const npa = require('npm-package-arg') const npmFetch = require('npm-registry-fetch') const pacote = require('pacote') -const log = require('../utils/log-shim') +const { log, output } = require('proc-log') const otplease = require('../utils/otplease.js') const pkgJson = require('@npmcli/package-json') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') const { redact } = require('@npmcli/redact') const readJson = async (path) => { @@ -115,9 +115,9 @@ class Owner extends BaseCommand { const packumentOpts = { ...this.npm.flatOptions, fullMetadata: true, preferOnline: true } const { maintainers } = await pacote.packument(spec, packumentOpts) if (!maintainers || !maintainers.length) { - this.npm.output('no admin found') + output.standard('no admin found') } else { - this.npm.output(maintainers.map(m => `${m.name} <${m.email}>`).join('\n')) + output.standard(maintainers.map(m => `${m.name} <${m.email}>`).join('\n')) } } catch (err) { log.error('owner ls', "Couldn't get owner data", redact(pkg)) @@ -216,9 +216,9 @@ class Owner extends BaseCommand { }) }) if (addOrRm === 'add') { - this.npm.output(`+ ${user} (${spec.name})`) + output.standard(`+ ${user} (${spec.name})`) } else { - this.npm.output(`- ${user} (${spec.name})`) + output.standard(`- ${user} (${spec.name})`) } return res } catch (err) { diff --git a/deps/npm/lib/commands/pack.js b/deps/npm/lib/commands/pack.js index 6d5f00df55e3fc..f64a21dcc0d9de 100644 --- a/deps/npm/lib/commands/pack.js +++ b/deps/npm/lib/commands/pack.js @@ -1,9 +1,9 @@ const pacote = require('pacote') const libpack = require('libnpmpack') const npa = require('npm-package-arg') -const log = require('../utils/log-shim') +const { log, output } = require('proc-log') const { getContents, logTar } = require('../utils/tar.js') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') class Pack extends BaseCommand { static description = 'Create a tarball from a package' @@ -58,13 +58,13 @@ class Pack extends BaseCommand { } if (json) { - this.npm.output(JSON.stringify(tarballs, null, 2)) + output.standard(JSON.stringify(tarballs, null, 2)) return } for (const tar of tarballs) { logTar(tar, { unicode }) - this.npm.output(tar.filename.replace(/^@/, '').replace(/\//, '-')) + output.standard(tar.filename.replace(/^@/, '').replace(/\//, '-')) } } @@ -83,4 +83,5 @@ class Pack extends BaseCommand { return this.exec([...this.workspacePaths, ...args.filter(a => a !== '.')]) } } + module.exports = Pack diff --git a/deps/npm/lib/commands/ping.js b/deps/npm/lib/commands/ping.js index 2d60f5d69a8da6..0d057862baa8fe 100644 --- a/deps/npm/lib/commands/ping.js +++ b/deps/npm/lib/commands/ping.js @@ -1,14 +1,14 @@ const { redact } = require('@npmcli/redact') -const log = require('../utils/log-shim') +const { log, output } = require('proc-log') const pingUtil = require('../utils/ping.js') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') class Ping extends BaseCommand { static description = 'Ping npm registry' static params = ['registry'] static name = 'ping' - async exec (args) { + async exec () { const cleanRegistry = redact(this.npm.config.get('registry')) log.notice('PING', cleanRegistry) const start = Date.now() @@ -16,14 +16,15 @@ class Ping extends BaseCommand { const time = Date.now() - start log.notice('PONG', `${time}ms`) if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify({ + output.standard(JSON.stringify({ registry: cleanRegistry, time, details, }, null, 2)) } else if (Object.keys(details).length) { - log.notice('PONG', `${JSON.stringify(details, null, 2)}`) + log.notice('PONG', JSON.stringify(details, null, 2)) } } } + module.exports = Ping diff --git a/deps/npm/lib/commands/pkg.js b/deps/npm/lib/commands/pkg.js index 49a66823cca996..62553b15103e3b 100644 --- a/deps/npm/lib/commands/pkg.js +++ b/deps/npm/lib/commands/pkg.js @@ -1,5 +1,6 @@ +const { output } = require('proc-log') const PackageJson = require('@npmcli/package-json') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') const Queryable = require('../utils/queryable.js') class Pkg extends BaseCommand { @@ -62,7 +63,7 @@ class Pkg extends BaseCommand { } // when running in workspaces names, make sure to key by workspace // name the results of each value retrieved in each ws - this.npm.output(JSON.stringify(result, null, 2)) + output.standard(JSON.stringify(result, null, 2)) } async get (args) { @@ -85,7 +86,7 @@ class Pkg extends BaseCommand { // only outputs if not running with workspaces config // execWorkspaces will handle the output otherwise if (!this.workspaces) { - this.npm.output(JSON.stringify(result, null, 2)) + output.standard(JSON.stringify(result, null, 2)) } return result diff --git a/deps/npm/lib/commands/prefix.js b/deps/npm/lib/commands/prefix.js index 264b819fc7692a..da8702cf91caaf 100644 --- a/deps/npm/lib/commands/prefix.js +++ b/deps/npm/lib/commands/prefix.js @@ -1,4 +1,5 @@ -const BaseCommand = require('../base-command.js') +const { output } = require('proc-log') +const BaseCommand = require('../base-cmd.js') class Prefix extends BaseCommand { static description = 'Display prefix' @@ -6,8 +7,9 @@ class Prefix extends BaseCommand { static params = ['global'] static usage = ['[-g]'] - async exec (args) { - return this.npm.output(this.npm.prefix) + async exec () { + return output.standard(this.npm.prefix) } } + module.exports = Prefix diff --git a/deps/npm/lib/commands/profile.js b/deps/npm/lib/commands/profile.js index a7d4ac2f29fbe7..8eae6278549f56 100644 --- a/deps/npm/lib/commands/profile.js +++ b/deps/npm/lib/commands/profile.js @@ -1,13 +1,11 @@ -const inspect = require('util').inspect +const { inspect } = require('util') const { URL } = require('url') -const log = require('../utils/log-shim.js') +const { log, output } = require('proc-log') const npmProfile = require('npm-profile') const qrcodeTerminal = require('qrcode-terminal') -const Table = require('cli-table3') - const otplease = require('../utils/otplease.js') -const pulseTillDone = require('../utils/pulse-till-done.js') const readUserInfo = require('../utils/read-user-info.js') +const BaseCommand = require('../base-cmd.js') const qrcode = url => new Promise((resolve) => qrcodeTerminal.generate(url, resolve)) @@ -35,7 +33,6 @@ const writableProfileKeys = [ 'github', ] -const BaseCommand = require('../base-command.js') class Profile extends BaseCommand { static description = 'Change settings on your registry profile' static name = 'profile' @@ -80,8 +77,6 @@ class Profile extends BaseCommand { throw this.usageError() } - log.gauge.show('profile') - const [subcmd, ...opts] = args switch (subcmd) { @@ -106,16 +101,14 @@ class Profile extends BaseCommand { async get (args) { const tfa = 'two-factor auth' - const info = await pulseTillDone.withPromise( - npmProfile.get({ ...this.npm.flatOptions }) - ) + const info = await npmProfile.get({ ...this.npm.flatOptions }) if (!info.cidr_whitelist) { delete info.cidr_whitelist } if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify(info, null, 2)) + output.standard(JSON.stringify(info, null, 2)) return } @@ -147,23 +140,20 @@ class Profile extends BaseCommand { .filter((arg) => arg.trim() !== '') .map((arg) => cleaned[arg]) .join('\t') - this.npm.output(values) + output.standard(values) } else { if (this.npm.config.get('parseable')) { for (const key of Object.keys(info)) { if (key === 'tfa') { - this.npm.output(`${key}\t${cleaned[tfa]}`) + output.standard(`${key}\t${cleaned[tfa]}`) } else { - this.npm.output(`${key}\t${info[key]}`) + output.standard(`${key}\t${info[key]}`) } } } else { - const table = new Table() - for (const key of Object.keys(cleaned)) { - table.push({ [this.npm.chalk.bold(key)]: cleaned[key] }) + for (const [key, value] of Object.entries(cleaned)) { + output.standard(`${key}: ${value}`) } - - this.npm.output(table.toString()) } } } @@ -209,7 +199,7 @@ class Profile extends BaseCommand { } // FIXME: Work around to not clear everything other than what we're setting - const user = await pulseTillDone.withPromise(npmProfile.get(conf)) + const user = await npmProfile.get(conf) const newUser = {} for (const key of writableProfileKeys) { @@ -221,13 +211,13 @@ class Profile extends BaseCommand { const result = await otplease(this.npm, conf, c => npmProfile.set(newUser, c)) if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify({ [prop]: result[prop] }, null, 2)) + output.standard(JSON.stringify({ [prop]: result[prop] }, null, 2)) } else if (this.npm.config.get('parseable')) { - this.npm.output(prop + '\t' + result[prop]) + output.standard(prop + '\t' + result[prop]) } else if (result[prop] != null) { - this.npm.output('Set', prop, 'to', result[prop]) + output.standard('Set', prop, 'to', result[prop]) } else { - this.npm.output('Set', prop) + output.standard('Set', prop) } } @@ -307,16 +297,12 @@ class Profile extends BaseCommand { info.tfa.password = password log.info('profile', 'Determine if tfa is pending') - const userInfo = await pulseTillDone.withPromise( - npmProfile.get({ ...this.npm.flatOptions }) - ) + const userInfo = await npmProfile.get({ ...this.npm.flatOptions }) const conf = { ...this.npm.flatOptions } if (userInfo && userInfo.tfa && userInfo.tfa.pending) { log.info('profile', 'Resetting two-factor authentication') - await pulseTillDone.withPromise( - npmProfile.set({ tfa: { password, mode: 'disable' } }, conf) - ) + await npmProfile.set({ tfa: { password, mode: 'disable' } }, conf) } else if (userInfo && userInfo.tfa) { if (!conf.otp) { conf.otp = await readUserInfo.otp( @@ -326,12 +312,10 @@ class Profile extends BaseCommand { } log.info('profile', 'Setting two-factor authentication to ' + mode) - const challenge = await pulseTillDone.withPromise( - npmProfile.set(info, conf) - ) + const challenge = await npmProfile.set(info, conf) if (challenge.tfa === null) { - this.npm.output('Two factor authentication mode changed to: ' + mode) + output.standard('Two factor authentication mode changed to: ' + mode) return } @@ -348,7 +332,7 @@ class Profile extends BaseCommand { const secret = otpauth.searchParams.get('secret') const code = await qrcode(challenge.tfa) - this.npm.output( + output.standard( 'Scan into your authenticator app:\n' + code + '\n Or enter code:', secret ) @@ -359,26 +343,26 @@ class Profile extends BaseCommand { const result = await npmProfile.set({ tfa: [interactiveOTP] }, conf) - this.npm.output( + output.standard( '2FA successfully enabled. Below are your recovery codes, ' + 'please print these out.' ) - this.npm.output( + output.standard( 'You will need these to recover access to your account ' + 'if you lose your authentication device.' ) for (const tfaCode of result.tfa) { - this.npm.output('\t' + tfaCode) + output.standard('\t' + tfaCode) } } - async disable2fa (args) { + async disable2fa () { const conf = { ...this.npm.flatOptions } - const info = await pulseTillDone.withPromise(npmProfile.get(conf)) + const info = await npmProfile.get(conf) if (!info.tfa || info.tfa.pending) { - this.npm.output('Two factor authentication not enabled.') + output.standard('Two factor authentication not enabled.') return } @@ -391,17 +375,16 @@ class Profile extends BaseCommand { log.info('profile', 'disabling tfa') - await pulseTillDone.withPromise(npmProfile.set({ - tfa: { password: password, mode: 'disable' }, - }, conf)) + await npmProfile.set({ tfa: { password: password, mode: 'disable' } }, conf) if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify({ tfa: false }, null, 2)) + output.standard(JSON.stringify({ tfa: false }, null, 2)) } else if (this.npm.config.get('parseable')) { - this.npm.output('tfa\tfalse') + output.standard('tfa\tfalse') } else { - this.npm.output('Two factor authentication disabled.') + output.standard('Two factor authentication disabled.') } } } + module.exports = Profile diff --git a/deps/npm/lib/commands/prune.js b/deps/npm/lib/commands/prune.js index 189fc29cb8bc35..1bcf8a9576316c 100644 --- a/deps/npm/lib/commands/prune.js +++ b/deps/npm/lib/commands/prune.js @@ -1,7 +1,7 @@ -// prune extraneous packages const reifyFinish = require('../utils/reify-finish.js') - const ArboristWorkspaceCmd = require('../arborist-cmd.js') + +// prune extraneous packages class Prune extends ArboristWorkspaceCmd { static description = 'Remove extraneous packages' static name = 'prune' @@ -30,4 +30,5 @@ class Prune extends ArboristWorkspaceCmd { await reifyFinish(this.npm, arb) } } + module.exports = Prune diff --git a/deps/npm/lib/commands/publish.js b/deps/npm/lib/commands/publish.js index cf6b50cce3c21c..6bb2dcc6614bb2 100644 --- a/deps/npm/lib/commands/publish.js +++ b/deps/npm/lib/commands/publish.js @@ -1,4 +1,4 @@ -const log = require('../utils/log-shim.js') +const { log, output } = require('proc-log') const semver = require('semver') const pack = require('libnpmpack') const libpub = require('libnpmpublish').publish @@ -7,18 +7,16 @@ const pacote = require('pacote') const npa = require('npm-package-arg') const npmFetch = require('npm-registry-fetch') const { redactLog: replaceInfo } = require('@npmcli/redact') - const otplease = require('../utils/otplease.js') const { getContents, logTar } = require('../utils/tar.js') - // for historical reasons, publishConfig in package.json can contain ANY config // keys that npm supports in .npmrc files and elsewhere. We *may* want to // revisit this at some point, and have a minimal set that's a SemVer-major // change that ought to get a RFC written on it. const { flatten } = require('@npmcli/config/lib/definitions') const pkgJson = require('@npmcli/package-json') +const BaseCommand = require('../base-cmd.js') -const BaseCommand = require('../base-command.js') class Publish extends BaseCommand { static description = 'Publish a package' static name = 'publish' @@ -59,7 +57,6 @@ class Publish extends BaseCommand { } const opts = { ...this.npm.flatOptions, progress: false } - log.disableProgress() // you can publish name@version, ./foo.tgz, etc. // even though the default is the 'file:.' cwd. @@ -73,7 +70,6 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, - banner: !silent, }) } @@ -132,7 +128,6 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, - banner: !silent, }) await runScript({ @@ -140,22 +135,21 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, - banner: !silent, }) } if (!this.suppressOutput) { if (!silent && json) { - this.npm.output(JSON.stringify(pkgContents, null, 2)) + output.standard(JSON.stringify(pkgContents, null, 2)) } else if (!silent) { - this.npm.output(`+ ${pkgContents.id}`) + output.standard(`+ ${pkgContents.id}`) } } return pkgContents } - async execWorkspaces (args) { + async execWorkspaces () { // Suppresses JSON output in publish() so we can handle it here this.suppressOutput = true @@ -173,7 +167,7 @@ class Publish extends BaseCommand { log.warn( 'publish', `Skipping workspace ${ - this.npm.chalk.green(name) + this.npm.chalk.cyan(name) }, marked as ${ this.npm.chalk.bold('private') }` @@ -185,14 +179,14 @@ class Publish extends BaseCommand { // This needs to be in-line w/ the rest of the output that non-JSON // publish generates if (!silent && !json) { - this.npm.output(`+ ${pkgContents.id}`) + output.standard(`+ ${pkgContents.id}`) } else { results[name] = pkgContents } } if (!silent && json) { - this.npm.output(JSON.stringify(results, null, 2)) + output.standard(JSON.stringify(results, null, 2)) } } @@ -230,4 +224,5 @@ class Publish extends BaseCommand { return manifest } } + module.exports = Publish diff --git a/deps/npm/lib/commands/query.js b/deps/npm/lib/commands/query.js index dfa1356ebf436d..fe84469b88fe0a 100644 --- a/deps/npm/lib/commands/query.js +++ b/deps/npm/lib/commands/query.js @@ -1,8 +1,6 @@ -'use strict' - -const { resolve } = require('path') -const BaseCommand = require('../base-command.js') -const log = require('../utils/log-shim.js') +const { resolve } = require('node:path') +const BaseCommand = require('../base-cmd.js') +const { log, output } = require('proc-log') class QuerySelectorItem { constructor (node) { @@ -83,7 +81,7 @@ class Query extends BaseCommand { this.buildResponse(items) this.checkExpected(this.#response.length) - this.npm.output(this.parsedResponse) + output.standard(this.parsedResponse) } async execWorkspaces (args) { @@ -107,7 +105,7 @@ class Query extends BaseCommand { this.buildResponse(items) } this.checkExpected(this.#response.length) - this.npm.output(this.parsedResponse) + output.standard(this.parsedResponse) } // builds a normalized inventory diff --git a/deps/npm/lib/commands/rebuild.js b/deps/npm/lib/commands/rebuild.js index 8af96f725555cb..3894f0aa290cc7 100644 --- a/deps/npm/lib/commands/rebuild.js +++ b/deps/npm/lib/commands/rebuild.js @@ -1,8 +1,9 @@ const { resolve } = require('path') +const { output } = require('proc-log') const npa = require('npm-package-arg') const semver = require('semver') - const ArboristWorkspaceCmd = require('../arborist-cmd.js') + class Rebuild extends ArboristWorkspaceCmd { static description = 'Rebuild a package' static name = 'rebuild' @@ -19,7 +20,7 @@ class Rebuild extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ static async completion (opts, npm) { - const completion = require('../utils/completion/installed-deep.js') + const completion = require('../utils/installed-deep.js') return completion(npm, opts) } @@ -56,7 +57,7 @@ class Rebuild extends ArboristWorkspaceCmd { await arb.rebuild() } - this.npm.output('rebuilt dependencies successfully') + output.standard('rebuilt dependencies successfully') } isNode (specs, node) { @@ -79,4 +80,5 @@ class Rebuild extends ArboristWorkspaceCmd { }) } } + module.exports = Rebuild diff --git a/deps/npm/lib/commands/repo.js b/deps/npm/lib/commands/repo.js index b89b74c0bf1baa..8e2fef24771d9d 100644 --- a/deps/npm/lib/commands/repo.js +++ b/deps/npm/lib/commands/repo.js @@ -1,6 +1,6 @@ const { URL } = require('url') - const PackageUrlCmd = require('../package-url-cmd.js') + class Repo extends PackageUrlCmd { static description = 'Open package repository page in the browser' static name = 'repo' @@ -30,6 +30,7 @@ class Repo extends PackageUrlCmd { return url } } + module.exports = Repo const unknownHostedUrl = url => { diff --git a/deps/npm/lib/commands/root.js b/deps/npm/lib/commands/root.js index 7749c602456b77..180f4c4ed0720a 100644 --- a/deps/npm/lib/commands/root.js +++ b/deps/npm/lib/commands/root.js @@ -1,11 +1,14 @@ -const BaseCommand = require('../base-command.js') +const { output } = require('proc-log') +const BaseCommand = require('../base-cmd.js') + class Root extends BaseCommand { static description = 'Display npm root' static name = 'root' static params = ['global'] async exec () { - this.npm.output(this.npm.dir) + output.standard(this.npm.dir) } } + module.exports = Root diff --git a/deps/npm/lib/commands/run-script.js b/deps/npm/lib/commands/run-script.js index 75f00a46b84e9f..dd00c98fc8b6ec 100644 --- a/deps/npm/lib/commands/run-script.js +++ b/deps/npm/lib/commands/run-script.js @@ -1,22 +1,7 @@ -const runScript = require('@npmcli/run-script') -const { isServerPackage } = runScript +const { log, output } = require('proc-log') const pkgJson = require('@npmcli/package-json') -const log = require('../utils/log-shim.js') -const didYouMean = require('../utils/did-you-mean.js') -const { isWindowsShell } = require('../utils/is-windows.js') - -const cmdList = [ - 'publish', - 'install', - 'uninstall', - 'test', - 'stop', - 'start', - 'restart', - 'version', -].reduce((l, p) => l.concat(['pre' + p, p, 'post' + p]), []) - -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') + class RunScript extends BaseCommand { static description = 'Run arbitrary package scripts' static params = [ @@ -39,7 +24,7 @@ class RunScript extends BaseCommand { const argv = opts.conf.argv.remain if (argv.length === 2) { const { content: { scripts = {} } } = await pkgJson.normalize(npm.localPrefix) - .catch(er => ({ content: {} })) + .catch(() => ({ content: {} })) if (opts.isFish) { return Object.keys(scripts).map(s => `${s}\t${scripts[s].slice(0, 30)}`) } @@ -64,9 +49,7 @@ class RunScript extends BaseCommand { } async run ([event, ...args], { path = this.npm.localPrefix, pkg } = {}) { - // this || undefined is because runScript will be unhappy with the default - // null value - const scriptShell = this.npm.config.get('script-shell') || undefined + const runScript = require('@npmcli/run-script') if (!pkg) { const { content } = await pkgJson.normalize(path) @@ -77,6 +60,7 @@ class RunScript extends BaseCommand { if (event === 'restart' && !scripts.restart) { scripts.restart = 'npm stop --if-present && npm start' } else if (event === 'env' && !scripts.env) { + const { isWindowsShell } = require('../utils/is-windows.js') scripts.env = isWindowsShell ? 'SET' : 'env' } @@ -84,12 +68,13 @@ class RunScript extends BaseCommand { if ( !Object.prototype.hasOwnProperty.call(scripts, event) && - !(event === 'start' && (await isServerPackage(path))) + !(event === 'start' && (await runScript.isServerPackage(path))) ) { if (this.npm.config.get('if-present')) { return } + const didYouMean = require('../utils/did-you-mean.js') const suggestions = await didYouMean(path, event) throw new Error( `Missing script: "${event}"${suggestions}\n\nTo see a list of scripts, run:\n npm run` @@ -108,18 +93,14 @@ class RunScript extends BaseCommand { } } - const opts = { - path, - args, - scriptShell, - stdio: 'inherit', - pkg, - banner: !this.npm.silent, - } - for (const [ev, evArgs] of events) { await runScript({ - ...opts, + path, + // this || undefined is because runScript will be unhappy with the + // default null value + scriptShell: this.npm.config.get('script-shell') || undefined, + stdio: 'inherit', + pkg, event: ev, args: evArgs, }) @@ -141,18 +122,29 @@ class RunScript extends BaseCommand { } if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify(scripts, null, 2)) + output.standard(JSON.stringify(scripts, null, 2)) return allScripts } if (this.npm.config.get('parseable')) { for (const [script, cmd] of Object.entries(scripts)) { - this.npm.output(`${script}:${cmd}`) + output.standard(`${script}:${cmd}`) } return allScripts } + // TODO this is missing things like prepare, prepublishOnly, and dependencies + const cmdList = [ + 'preinstall', 'install', 'postinstall', + 'prepublish', 'publish', 'postpublish', + 'prerestart', 'restart', 'postrestart', + 'prestart', 'start', 'poststart', + 'prestop', 'stop', 'poststop', + 'pretest', 'test', 'posttest', + 'preuninstall', 'uninstall', 'postuninstall', + 'preversion', 'version', 'postversion', + ] const indent = '\n ' const prefix = ' ' const cmds = [] @@ -164,7 +156,7 @@ class RunScript extends BaseCommand { const colorize = this.npm.chalk if (cmds.length) { - this.npm.output( + output.standard( `${colorize.reset(colorize.bold('Lifecycle scripts'))} included in ${colorize.green( pkgid )}:` @@ -172,28 +164,28 @@ class RunScript extends BaseCommand { } for (const script of cmds) { - this.npm.output(prefix + script + indent + colorize.dim(scripts[script])) + output.standard(prefix + script + indent + colorize.dim(scripts[script])) } if (!cmds.length && runScripts.length) { - this.npm.output( + output.standard( `${colorize.bold('Scripts')} available in ${colorize.green(pkgid)} via \`${colorize.blue( 'npm run-script' )}\`:` ) } else if (runScripts.length) { - this.npm.output(`\navailable via \`${colorize.blue('npm run-script')}\`:`) + output.standard(`\navailable via \`${colorize.blue('npm run-script')}\`:`) } for (const script of runScripts) { - this.npm.output(prefix + script + indent + colorize.dim(scripts[script])) + output.standard(prefix + script + indent + colorize.dim(scripts[script])) } - this.npm.output('') + output.standard('') return allScripts } - async runWorkspaces (args, filters) { + async runWorkspaces (args) { const res = [] await this.setWorkspaces() @@ -213,7 +205,7 @@ class RunScript extends BaseCommand { } } - async listWorkspaces (args, filters) { + async listWorkspaces (args) { await this.setWorkspaces() if (this.npm.silent) { @@ -226,7 +218,7 @@ class RunScript extends BaseCommand { const { content: { scripts, name } } = await pkgJson.normalize(workspacePath) res[name] = { ...scripts } } - this.npm.output(JSON.stringify(res, null, 2)) + output.standard(JSON.stringify(res, null, 2)) return } @@ -234,7 +226,7 @@ class RunScript extends BaseCommand { for (const workspacePath of this.workspacePaths) { const { content: { scripts, name } } = await pkgJson.normalize(workspacePath) for (const [script, cmd] of Object.entries(scripts || {})) { - this.npm.output(`${name}:${script}:${cmd}`) + output.standard(`${name}:${script}:${cmd}`) } } return diff --git a/deps/npm/lib/commands/sbom.js b/deps/npm/lib/commands/sbom.js index 311dfbc852406d..ff7377581dfa51 100644 --- a/deps/npm/lib/commands/sbom.js +++ b/deps/npm/lib/commands/sbom.js @@ -1,9 +1,6 @@ -'use strict' - -const { EOL } = require('os') const localeCompare = require('@isaacs/string-locale-compare')('en') -const BaseCommand = require('../base-command.js') -const log = require('../utils/log-shim.js') +const BaseCommand = require('../base-cmd.js') +const { log, output } = require('proc-log') const { cyclonedxOutput } = require('../utils/sbom-cyclonedx.js') const { spdxOutput } = require('../utils/sbom-spdx.js') @@ -77,7 +74,7 @@ class SBOM extends BaseCommand { if (errors.size > 0) { throw Object.assign( - new Error([...errors].join(EOL)), + new Error([...errors].join('\n')), { code: 'ESBOMPROBLEMS' } ) } @@ -87,7 +84,7 @@ class SBOM extends BaseCommand { items .sort((a, b) => localeCompare(a.location, b.location)) ) - this.npm.output(this.#parsedResponse) + output.standard(this.#parsedResponse) } async execWorkspaces (args) { diff --git a/deps/npm/lib/commands/search.js b/deps/npm/lib/commands/search.js index bb94d6da20f1c1..8b6c01e3930d81 100644 --- a/deps/npm/lib/commands/search.js +++ b/deps/npm/lib/commands/search.js @@ -1,43 +1,13 @@ -const { Minipass } = require('minipass') const Pipeline = require('minipass-pipeline') const libSearch = require('libnpmsearch') -const log = require('../utils/log-shim.js') - +const { log, output } = require('proc-log') const formatSearchStream = require('../utils/format-search-stream.js') +const BaseCommand = require('../base-cmd.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 - } - - return true -} - -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 words.indexOf(pattern) !== -1 -} - -const BaseCommand = require('../base-command.js') class Search extends BaseCommand { static description = 'Search for packages' static name = 'search' static params = [ - 'long', 'json', 'color', 'parseable', @@ -51,13 +21,13 @@ class Search extends BaseCommand { 'offline', ] - static usage = ['[search terms ...]'] + static usage = [' [ ...]'] async exec (args) { const opts = { ...this.npm.flatOptions, ...this.npm.flatOptions.search, - include: args.map(s => s.toLowerCase()).filter(s => s), + include: args.map(s => s.toLowerCase()).filter(Boolean), exclude: this.npm.flatOptions.search.exclude.split(/\s+/), } @@ -68,30 +38,16 @@ class Search extends BaseCommand { // Used later to figure out whether we had any packages go out let anyOutput = false - class FilterStream extends Minipass { - constructor () { - super({ objectMode: true }) - } - - write (pkg) { - if (filter(pkg, opts.include, opts.exclude)) { - super.write(pkg) - } - } - } - - const filterStream = new FilterStream() - // Grab a configured output stream that will spit out packages in the desired format. - const outputStream = await formatSearchStream({ + const outputStream = formatSearchStream({ args, // --searchinclude options are not highlighted ...opts, + npm: this.npm, }) log.silly('search', 'searching packages') const p = new Pipeline( libSearch.stream(opts.include, opts), - filterStream, outputStream ) @@ -99,16 +55,16 @@ class Search extends BaseCommand { if (!anyOutput) { anyOutput = true } - this.npm.output(chunk.toString('utf8')) + output.standard(chunk.toString('utf8')) }) await p.promise() if (!anyOutput && !this.npm.config.get('json') && !this.npm.config.get('parseable')) { - this.npm.output('No matches found for ' + (args.map(JSON.stringify).join(' '))) + output.standard('No matches found for ' + (args.map(JSON.stringify).join(' '))) } log.silly('search', 'search completed') - log.clearProgress() } } + module.exports = Search diff --git a/deps/npm/lib/commands/set.js b/deps/npm/lib/commands/set.js index f315d183845c5e..2e61762ba9dcd4 100644 --- a/deps/npm/lib/commands/set.js +++ b/deps/npm/lib/commands/set.js @@ -1,5 +1,5 @@ const Npm = require('../npm.js') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') class Set extends BaseCommand { static description = 'Set a value in the npm configuration' @@ -22,4 +22,5 @@ class Set extends BaseCommand { return this.npm.exec('config', ['set'].concat(args)) } } + module.exports = Set diff --git a/deps/npm/lib/commands/shrinkwrap.js b/deps/npm/lib/commands/shrinkwrap.js index c6d817d4801423..d7866bdb91dceb 100644 --- a/deps/npm/lib/commands/shrinkwrap.js +++ b/deps/npm/lib/commands/shrinkwrap.js @@ -1,7 +1,8 @@ const { resolve, basename } = require('path') -const { unlink } = require('fs').promises -const log = require('../utils/log-shim') -const BaseCommand = require('../base-command.js') +const { unlink } = require('fs/promises') +const { log } = require('proc-log') +const BaseCommand = require('../base-cmd.js') + class Shrinkwrap extends BaseCommand { static description = 'Lock down dependency versions for publication' static name = 'shrinkwrap' @@ -68,4 +69,5 @@ class Shrinkwrap extends BaseCommand { } } } + module.exports = Shrinkwrap diff --git a/deps/npm/lib/commands/star.js b/deps/npm/lib/commands/star.js index 20039bf8938116..1b76955810c726 100644 --- a/deps/npm/lib/commands/star.js +++ b/deps/npm/lib/commands/star.js @@ -1,9 +1,9 @@ const fetch = require('npm-registry-fetch') const npa = require('npm-package-arg') -const log = require('../utils/log-shim') +const { log, output } = require('proc-log') const getIdentity = require('../utils/get-identity') +const BaseCommand = require('../base-cmd.js') -const BaseCommand = require('../base-command.js') class Star extends BaseCommand { static description = 'Mark your favorite packages' static name = 'star' @@ -62,10 +62,11 @@ class Star extends BaseCommand { body, }) - this.npm.output(show + ' ' + pkg.name) + output.standard(show + ' ' + pkg.name) log.verbose('star', data) return data } } } + module.exports = Star diff --git a/deps/npm/lib/commands/stars.js b/deps/npm/lib/commands/stars.js index 4214134eb5871a..1059569979dafe 100644 --- a/deps/npm/lib/commands/stars.js +++ b/deps/npm/lib/commands/stars.js @@ -1,8 +1,8 @@ const fetch = require('npm-registry-fetch') -const log = require('../utils/log-shim') +const { log, output } = require('proc-log') const getIdentity = require('../utils/get-identity.js') +const BaseCommand = require('../base-cmd.js') -const BaseCommand = require('../base-command.js') class Stars extends BaseCommand { static description = 'View packages marked as favorites' static name = 'stars' @@ -25,7 +25,7 @@ class Stars extends BaseCommand { } for (const row of rows) { - this.npm.output(row.value) + output.standard(row.value) } } catch (err) { if (err.code === 'ENEEDAUTH') { @@ -35,4 +35,5 @@ class Stars extends BaseCommand { } } } + module.exports = Stars diff --git a/deps/npm/lib/commands/team.js b/deps/npm/lib/commands/team.js index 3c6cf305a6e5f9..22af61863851ab 100644 --- a/deps/npm/lib/commands/team.js +++ b/deps/npm/lib/commands/team.js @@ -1,9 +1,9 @@ const columns = require('cli-columns') const libteam = require('libnpmteam') - +const { output } = require('proc-log') const otplease = require('../utils/otplease.js') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') class Team extends BaseCommand { static description = 'Manage organization teams and team memberships' static name = 'team' @@ -68,87 +68,88 @@ class Team extends BaseCommand { async create (entity, opts) { await libteam.create(entity, opts) if (opts.json) { - this.npm.output(JSON.stringify({ + output.standard(JSON.stringify({ created: true, team: entity, })) } else if (opts.parseable) { - this.npm.output(`${entity}\tcreated`) + output.standard(`${entity}\tcreated`) } else if (!this.npm.silent) { - this.npm.output(`+@${entity}`) + output.standard(`+@${entity}`) } } async destroy (entity, opts) { await libteam.destroy(entity, opts) if (opts.json) { - this.npm.output(JSON.stringify({ + output.standard(JSON.stringify({ deleted: true, team: entity, })) } else if (opts.parseable) { - this.npm.output(`${entity}\tdeleted`) + output.standard(`${entity}\tdeleted`) } else if (!this.npm.silent) { - this.npm.output(`-@${entity}`) + output.standard(`-@${entity}`) } } async add (entity, user, opts) { await libteam.add(user, entity, opts) if (opts.json) { - this.npm.output(JSON.stringify({ + output.standard(JSON.stringify({ added: true, team: entity, user, })) } else if (opts.parseable) { - this.npm.output(`${user}\t${entity}\tadded`) + output.standard(`${user}\t${entity}\tadded`) } else if (!this.npm.silent) { - this.npm.output(`${user} added to @${entity}`) + output.standard(`${user} added to @${entity}`) } } async rm (entity, user, opts) { await libteam.rm(user, entity, opts) if (opts.json) { - this.npm.output(JSON.stringify({ + output.standard(JSON.stringify({ removed: true, team: entity, user, })) } else if (opts.parseable) { - this.npm.output(`${user}\t${entity}\tremoved`) + output.standard(`${user}\t${entity}\tremoved`) } else if (!this.npm.silent) { - this.npm.output(`${user} removed from @${entity}`) + output.standard(`${user} removed from @${entity}`) } } async listUsers (entity, opts) { const users = (await libteam.lsUsers(entity, opts)).sort() if (opts.json) { - this.npm.output(JSON.stringify(users, null, 2)) + output.standard(JSON.stringify(users, null, 2)) } else if (opts.parseable) { - this.npm.output(users.join('\n')) + output.standard(users.join('\n')) } else if (!this.npm.silent) { const plural = users.length === 1 ? '' : 's' const more = users.length === 0 ? '' : ':\n' - this.npm.output(`\n@${entity} has ${users.length} user${plural}${more}`) - this.npm.output(columns(users, { padding: 1 })) + output.standard(`\n@${entity} has ${users.length} user${plural}${more}`) + output.standard(columns(users, { padding: 1 })) } } async listTeams (entity, opts) { const teams = (await libteam.lsTeams(entity, opts)).sort() if (opts.json) { - this.npm.output(JSON.stringify(teams, null, 2)) + output.standard(JSON.stringify(teams, null, 2)) } else if (opts.parseable) { - this.npm.output(teams.join('\n')) + output.standard(teams.join('\n')) } else if (!this.npm.silent) { const plural = teams.length === 1 ? '' : 's' const more = teams.length === 0 ? '' : ':\n' - this.npm.output(`\n@${entity} has ${teams.length} team${plural}${more}`) - this.npm.output(columns(teams.map(t => `@${t}`), { padding: 1 })) + output.standard(`\n@${entity} has ${teams.length} team${plural}${more}`) + output.standard(columns(teams.map(t => `@${t}`), { padding: 1 })) } } } + module.exports = Team diff --git a/deps/npm/lib/commands/token.js b/deps/npm/lib/commands/token.js index dc1df6e0fcb25b..24ca21a8e29ce9 100644 --- a/deps/npm/lib/commands/token.js +++ b/deps/npm/lib/commands/token.js @@ -1,12 +1,9 @@ -const Table = require('cli-table3') -const log = require('../utils/log-shim.js') +const { log, output } = require('proc-log') const profile = require('npm-profile') - const otplease = require('../utils/otplease.js') -const pulseTillDone = require('../utils/pulse-till-done.js') const readUserInfo = require('../utils/read-user-info.js') +const BaseCommand = require('../base-cmd.js') -const BaseCommand = require('../base-command.js') class Token extends BaseCommand { static description = 'Manage your authentication tokens' static name = 'token' @@ -28,7 +25,6 @@ class Token extends BaseCommand { } async exec (args) { - log.gauge.show('token') if (args.length === 0) { return this.list() } @@ -36,10 +32,10 @@ class Token extends BaseCommand { case 'list': case 'ls': return this.list() + case 'rm': case 'delete': case 'revoke': case 'remove': - case 'rm': return this.rm(args.slice(1)) case 'create': return this.create(args.slice(1)) @@ -49,16 +45,18 @@ class Token extends BaseCommand { } async list () { - const conf = this.config() + const json = this.npm.config.get('json') + const parseable = this.npm.config.get('parseable') log.info('token', 'getting list') - const tokens = await pulseTillDone.withPromise(profile.listTokens(conf)) - if (conf.json) { - this.npm.output(JSON.stringify(tokens, null, 2)) + const tokens = await profile.listTokens(this.npm.flatOptions) + if (json) { + output.standard(JSON.stringify(tokens, null, 2)) return - } else if (conf.parseable) { - this.npm.output(['key', 'token', 'created', 'readonly', 'CIDR whitelist'].join('\t')) + } + if (parseable) { + output.standard(['key', 'token', 'created', 'readonly', 'CIDR whitelist'].join('\t')) tokens.forEach(token => { - this.npm.output( + output.standard( [ token.key, token.token, @@ -71,21 +69,17 @@ class Token extends BaseCommand { return } this.generateTokenIds(tokens, 6) - const idWidth = tokens.reduce((acc, token) => Math.max(acc, token.id.length), 0) - const table = new Table({ - head: ['id', 'token', 'created', 'readonly', 'CIDR whitelist'], - colWidths: [Math.max(idWidth, 2) + 2, 9, 12, 10], - }) - tokens.forEach(token => { - table.push([ - token.id, - token.token + '…', - String(token.created).slice(0, 10), - token.readonly ? 'yes' : 'no', - token.cidr_whitelist ? token.cidr_whitelist.join(', ') : '', - ]) - }) - this.npm.output(table.toString()) + const chalk = this.npm.chalk + for (const token of tokens) { + const level = token.readonly ? 'Read only token' : 'Publish token' + const created = String(token.created).slice(0, 10) + /* eslint-disable-next-line max-len */ + output.standard(`${chalk.blue(level)} ${token.token}… with id ${chalk.cyan(token.id)} created ${created}`) + if (token.cidr_whitelist) { + output.standard(`with IP whitelist: ${chalk.green(token.cidr_whitelist.join(','))}`) + } + output.standard() + } } async rm (args) { @@ -93,11 +87,12 @@ class Token extends BaseCommand { throw this.usageError('`` argument is required.') } - const conf = this.config() + const json = this.npm.config.get('json') + const parseable = this.npm.config.get('parseable') const toRemove = [] - const progress = log.newItem('removing tokens', toRemove.length) - progress.info('token', 'getting existing list') - const tokens = await pulseTillDone.withPromise(profile.listTokens(conf)) + const opts = { ...this.npm.flatOptions } + log.info('token', `removing ${toRemove.length} tokens`) + const tokens = await profile.listTokens(opts) args.forEach(id => { const matches = tokens.filter(token => token.key.indexOf(id) === 0) if (matches.length === 1) { @@ -118,72 +113,47 @@ class Token extends BaseCommand { }) await Promise.all( toRemove.map(key => { - return otplease(this.npm, conf, c => profile.removeToken(key, c)) + return otplease(this.npm, opts, c => profile.removeToken(key, c)) }) ) - if (conf.json) { - this.npm.output(JSON.stringify(toRemove)) - } else if (conf.parseable) { - this.npm.output(toRemove.join('\t')) + if (json) { + output.standard(JSON.stringify(toRemove)) + } else if (parseable) { + output.standard(toRemove.join('\t')) } else { - this.npm.output('Removed ' + toRemove.length + ' token' + (toRemove.length !== 1 ? 's' : '')) + output.standard('Removed ' + toRemove.length + ' token' + (toRemove.length !== 1 ? 's' : '')) } } - async create (args) { - const conf = this.config() - const cidr = conf.cidr - const readonly = conf.readOnly + async create () { + const json = this.npm.config.get('json') + const parseable = this.npm.config.get('parseable') + const cidr = this.npm.config.get('cidr') + const readonly = this.npm.config.get('read-only') - const password = await readUserInfo.password() const validCIDR = await this.validateCIDRList(cidr) + const password = await readUserInfo.password() log.info('token', 'creating') - const result = await pulseTillDone.withPromise( - otplease(this.npm, conf, c => profile.createToken(password, readonly, validCIDR, c)) + const result = await otplease( + this.npm, + { ...this.npm.flatOptions }, + c => profile.createToken(password, readonly, validCIDR, c) ) delete result.key delete result.updated - if (conf.json) { - this.npm.output(JSON.stringify(result)) - } else if (conf.parseable) { - Object.keys(result).forEach(k => this.npm.output(k + '\t' + result[k])) + if (json) { + output.standard(JSON.stringify(result)) + } else if (parseable) { + Object.keys(result).forEach(k => output.standard(k + '\t' + result[k])) } else { - const table = new Table() - for (const k of Object.keys(result)) { - table.push({ [this.npm.chalk.bold(k)]: String(result[k]) }) - } - this.npm.output(table.toString()) - } - } - - config () { - const conf = { ...this.npm.flatOptions } - const creds = this.npm.config.getCredentialsByURI(conf.registry) - if (creds.token) { - conf.auth = { token: creds.token } - } else if (creds.username) { - conf.auth = { - basic: { - username: creds.username, - password: creds.password, - }, + const chalk = this.npm.chalk + // Identical to list + const level = result.readonly ? 'read only' : 'publish' + output.standard(`Created ${chalk.blue(level)} token ${result.token}`) + if (result.cidr_whitelist?.length) { + output.standard(`with IP whitelist: ${chalk.green(result.cidr_whitelist.join(','))}`) } - } else if (creds.auth) { - const auth = Buffer.from(creds.auth, 'base64').toString().split(':', 2) - conf.auth = { - basic: { - username: auth[0], - password: auth[1], - }, - } - } else { - conf.auth = {} } - - if (conf.otp) { - conf.auth.otp = conf.otp - } - return conf } invalidCIDRError (msg) { @@ -191,7 +161,6 @@ class Token extends BaseCommand { } generateTokenIds (tokens, minLength) { - const byId = {} for (const token of tokens) { token.id = token.key for (let ii = minLength; ii < token.key.length; ++ii) { @@ -203,9 +172,7 @@ class Token extends BaseCommand { break } } - byId[token.id] = token } - return byId } async validateCIDRList (cidrs) { @@ -215,15 +182,16 @@ class Token extends BaseCommand { for (const cidr of list) { if (isCidrV6(cidr)) { throw this.invalidCIDRError( - 'CIDR whitelist can only contain IPv4 addresses, ' + cidr + ' is IPv6' + `CIDR whitelist can only contain IPv4 addresses${cidr} is IPv6` ) } if (!isCidrV4(cidr)) { - throw this.invalidCIDRError('CIDR whitelist contains invalid CIDR entry: ' + cidr) + throw this.invalidCIDRError(`CIDR whitelist contains invalid CIDR entry: ${cidr}`) } } return list } } + module.exports = Token diff --git a/deps/npm/lib/commands/uninstall.js b/deps/npm/lib/commands/uninstall.js index 07775efb9cf2f1..7496c02deb28f4 100644 --- a/deps/npm/lib/commands/uninstall.js +++ b/deps/npm/lib/commands/uninstall.js @@ -1,10 +1,9 @@ const { resolve } = require('path') const pkgJson = require('@npmcli/package-json') - const reifyFinish = require('../utils/reify-finish.js') -const completion = require('../utils/completion/installed-shallow.js') - +const completion = require('../utils/installed-shallow.js') const ArboristWorkspaceCmd = require('../arborist-cmd.js') + class Uninstall extends ArboristWorkspaceCmd { static description = 'Remove a package' static name = 'uninstall' @@ -53,4 +52,5 @@ class Uninstall extends ArboristWorkspaceCmd { await reifyFinish(this.npm, arb) } } + module.exports = Uninstall diff --git a/deps/npm/lib/commands/unpublish.js b/deps/npm/lib/commands/unpublish.js index a4d445a035b622..47a5db82062442 100644 --- a/deps/npm/lib/commands/unpublish.js +++ b/deps/npm/lib/commands/unpublish.js @@ -2,18 +2,17 @@ const libaccess = require('libnpmaccess') const libunpub = require('libnpmpublish').unpublish const npa = require('npm-package-arg') const pacote = require('pacote') +const { output, log } = require('proc-log') const pkgJson = require('@npmcli/package-json') - const { flatten } = require('@npmcli/config/lib/definitions') const getIdentity = require('../utils/get-identity.js') -const log = require('../utils/log-shim') const otplease = require('../utils/otplease.js') +const BaseCommand = require('../base-cmd.js') const LAST_REMAINING_VERSION_ERROR = 'Refusing to delete the last version of the package. ' + 'It will block from republishing a new version for 24 hours.\n' + 'Run with --force to do this.' -const BaseCommand = require('../base-command.js') class Unpublish extends BaseCommand { static description = 'Remove a package from the registry' static name = 'unpublish' @@ -161,7 +160,7 @@ class Unpublish extends BaseCommand { await otplease(this.npm, opts, o => libunpub(spec, o)) } if (!silent) { - this.npm.output(`- ${spec.name}${pkgVersion}`) + output.standard(`- ${spec.name}${pkgVersion}`) } } @@ -173,4 +172,5 @@ class Unpublish extends BaseCommand { } } } + module.exports = Unpublish diff --git a/deps/npm/lib/commands/unstar.js b/deps/npm/lib/commands/unstar.js index cbcb73636c6384..c72966866669a9 100644 --- a/deps/npm/lib/commands/unstar.js +++ b/deps/npm/lib/commands/unstar.js @@ -4,4 +4,5 @@ class Unstar extends Star { static description = 'Remove an item from your favorite packages' static name = 'unstar' } + module.exports = Unstar diff --git a/deps/npm/lib/commands/update.js b/deps/npm/lib/commands/update.js index 43d031c7ada3f3..ddc3e4a47f38a1 100644 --- a/deps/npm/lib/commands/update.js +++ b/deps/npm/lib/commands/update.js @@ -1,10 +1,8 @@ const path = require('path') - -const log = require('../utils/log-shim.js') - +const { log } = require('proc-log') const reifyFinish = require('../utils/reify-finish.js') - const ArboristWorkspaceCmd = require('../arborist-cmd.js') + class Update extends ArboristWorkspaceCmd { static description = 'Update packages' static name = 'update' @@ -33,7 +31,7 @@ class Update extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ static async completion (opts, npm) { - const completion = require('../utils/completion/installed-deep.js') + const completion = require('../utils/installed-deep.js') return completion(npm, opts) } @@ -66,4 +64,5 @@ class Update extends ArboristWorkspaceCmd { await reifyFinish(this.npm, arb) } } + module.exports = Update diff --git a/deps/npm/lib/commands/version.js b/deps/npm/lib/commands/version.js index 029a6fdd3101e4..549ba9b9f9c771 100644 --- a/deps/npm/lib/commands/version.js +++ b/deps/npm/lib/commands/version.js @@ -1,10 +1,7 @@ -const libnpmversion = require('libnpmversion') -const { resolve } = require('path') -const { promisify } = require('util') -const readFile = promisify(require('fs').readFile) - -const updateWorkspaces = require('../workspaces/update-workspaces.js') -const BaseCommand = require('../base-command.js') +const { resolve } = require('node:path') +const { readFile } = require('node:fs/promises') +const { output } = require('proc-log') +const BaseCommand = require('../base-cmd.js') class Version extends BaseCommand { static description = 'Bump a package version' @@ -73,29 +70,43 @@ class Version extends BaseCommand { } async change (args) { + const libnpmversion = require('libnpmversion') const prefix = this.npm.config.get('tag-version-prefix') const version = await libnpmversion(args[0], { ...this.npm.flatOptions, path: this.npm.prefix, }) - return this.npm.output(`${prefix}${version}`) + return output.standard(`${prefix}${version}`) } async changeWorkspaces (args) { + const updateWorkspaces = require('../utils/update-workspaces.js') + const libnpmversion = require('libnpmversion') const prefix = this.npm.config.get('tag-version-prefix') + const { + config, + flatOptions, + localPrefix, + } = this.npm await this.setWorkspaces() const updatedWorkspaces = [] for (const [name, path] of this.workspaces) { - this.npm.output(name) + output.standard(name) const version = await libnpmversion(args[0], { - ...this.npm.flatOptions, + ...flatOptions, 'git-tag-version': false, path, }) updatedWorkspaces.push(name) - this.npm.output(`${prefix}${version}`) + output.standard(`${prefix}${version}`) } - return this.update(updatedWorkspaces) + return updateWorkspaces({ + config, + flatOptions, + localPrefix, + npm: this.npm, + workspaces: updatedWorkspaces, + }) } async list (results = {}) { @@ -115,9 +126,9 @@ class Version extends BaseCommand { } if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify(results, null, 2)) + output.standard(JSON.stringify(results, null, 2)) } else { - this.npm.output(results) + output.standard(results) } } @@ -135,22 +146,6 @@ class Version extends BaseCommand { } return this.list(results) } - - async update (workspaces) { - const { - config, - flatOptions, - localPrefix, - } = this.npm - - await updateWorkspaces({ - config, - flatOptions, - localPrefix, - npm: this.npm, - workspaces, - }) - } } module.exports = Version diff --git a/deps/npm/lib/commands/view.js b/deps/npm/lib/commands/view.js index b19604f8c2ed35..c0d5bf552eee02 100644 --- a/deps/npm/lib/commands/view.js +++ b/deps/npm/lib/commands/view.js @@ -1,20 +1,19 @@ const columns = require('cli-columns') -const fs = require('fs') +const { readFile } = require('fs/promises') const jsonParse = require('json-parse-even-better-errors') -const log = require('../utils/log-shim.js') +const { log, output } = require('proc-log') const npa = require('npm-package-arg') const { resolve } = require('path') const formatBytes = require('../utils/format-bytes.js') const relativeDate = require('tiny-relative-date') const semver = require('semver') -const { inspect, promisify } = require('util') +const { inspect } = require('util') const { packument } = require('pacote') +const Queryable = require('../utils/queryable.js') +const BaseCommand = require('../base-cmd.js') -const readFile = promisify(fs.readFile) const readJson = async file => jsonParse(await readFile(file, 'utf8')) -const Queryable = require('../utils/queryable.js') -const BaseCommand = require('../base-command.js') class View extends BaseCommand { static description = 'View registry info' static name = 'view' @@ -115,13 +114,10 @@ class View extends BaseCommand { reducedData = cleanBlanks(reducedData) log.silly('view', reducedData) } - // disable the progress bar entirely, as we can't meaningfully update it - // if we may have partial lines printed. - log.disableProgress() const msg = await this.jsonData(reducedData, pckmnt._id) if (msg !== '') { - this.npm.output(msg) + output.standard(msg) } } } @@ -160,10 +156,10 @@ class View extends BaseCommand { if (wholePackument) { data.map((v) => this.prettyView(pckmnt, v[Object.keys(v)[0]][''])) } else { - this.npm.output(`${name}:`) + output.standard(`${name}:`) const msg = await this.jsonData(reducedData, pckmnt._id) if (msg !== '') { - this.npm.output(msg) + output.standard(msg) } } } else { @@ -174,7 +170,7 @@ class View extends BaseCommand { } } if (Object.keys(results).length > 0) { - this.npm.output(JSON.stringify(results, null, 2)) + output.standard(JSON.stringify(results, null, 2)) } } @@ -321,131 +317,96 @@ class View extends BaseCommand { // More modern, pretty printing of default view const unicode = this.npm.config.get('unicode') const chalk = this.npm.chalk - const tags = [] - - Object.keys(packu['dist-tags']).forEach((t) => { - const version = packu['dist-tags'][t] - tags.push(`${chalk.bold.green(t)}: ${version}`) - }) - const unpackedSize = manifest.dist.unpackedSize && - formatBytes(manifest.dist.unpackedSize, true) + const deps = Object.keys(manifest.dependencies || {}).map((dep) => + `${chalk.blue(dep)}: ${manifest.dependencies[dep]}` + ) + const site = manifest.homepage?.url || manifest.homepage + const bins = Object.keys(manifest.bin || {}) const licenseField = manifest.license || 'Proprietary' - const info = { - name: chalk.green(manifest.name), - version: chalk.green(manifest.version), - bins: Object.keys(manifest.bin || {}), - versions: chalk.yellow(packu.versions.length + ''), - description: manifest.description, - deprecated: manifest.deprecated, - keywords: packu.keywords || [], - license: typeof licenseField === 'string' - ? licenseField - : (licenseField.type || 'Proprietary'), - deps: Object.keys(manifest.dependencies || {}).map((dep) => { - return `${chalk.yellow(dep)}: ${manifest.dependencies[dep]}` - }), - publisher: manifest._npmUser && unparsePerson({ - name: chalk.yellow(manifest._npmUser.name), - email: chalk.cyan(manifest._npmUser.email), - }), - modified: !packu.time ? undefined - : chalk.yellow(relativeDate(packu.time[manifest.version])), - maintainers: (packu.maintainers || []).map((u) => unparsePerson({ - name: chalk.yellow(u.name), - email: chalk.cyan(u.email), - })), - repo: ( - manifest.bugs && (manifest.bugs.url || manifest.bugs) - ) || ( - manifest.repository && (manifest.repository.url || manifest.repository) - ), - site: ( - manifest.homepage && (manifest.homepage.url || manifest.homepage) - ), - tags, - tarball: chalk.cyan(manifest.dist.tarball), - shasum: chalk.yellow(manifest.dist.shasum), - integrity: - manifest.dist.integrity && chalk.yellow(manifest.dist.integrity), - fileCount: - manifest.dist.fileCount && chalk.yellow(manifest.dist.fileCount), - unpackedSize: unpackedSize && chalk.yellow(unpackedSize), - } - if (info.license.toLowerCase().trim() === 'proprietary') { - info.license = chalk.bold.red(info.license) - } else { - info.license = chalk.green(info.license) + const license = typeof licenseField === 'string' + ? licenseField + : (licenseField.type || 'Proprietary') + + output.standard('') + output.standard([ + chalk.underline.cyan(`${manifest.name}@${manifest.version}`), + license.toLowerCase().trim() === 'proprietary' + ? chalk.red(license) + : chalk.green(license), + `deps: ${deps.length ? chalk.cyan(deps.length) : chalk.cyan('none')}`, + `versions: ${chalk.cyan(packu.versions.length + '')}`, + ].join(' | ')) + + manifest.description && output.standard(manifest.description) + if (site) { + output.standard(chalk.blue(site)) } - this.npm.output('') - this.npm.output( - chalk.underline.bold(`${info.name}@${info.version}`) + - ' | ' + info.license + - ' | deps: ' + (info.deps.length ? chalk.cyan(info.deps.length) : chalk.green('none')) + - ' | versions: ' + info.versions + manifest.deprecated && output.standard( + `\n${chalk.redBright('DEPRECATED')}${unicode ? ' ⚠️ ' : '!!'} - ${manifest.deprecated}` ) - info.description && this.npm.output(info.description) - if (info.repo || info.site) { - info.site && this.npm.output(chalk.cyan(info.site)) - } - const warningSign = unicode ? ' ⚠️ ' : '!!' - info.deprecated && this.npm.output( - `\n${chalk.bold.red('DEPRECATED')}${ - warningSign - } - ${info.deprecated}` - ) + if (packu.keywords?.length) { + output.standard(`\nkeywords: ${ + packu.keywords.map(k => chalk.cyan(k)).join(', ') + }`) + } - if (info.keywords.length) { - this.npm.output('') - this.npm.output(`keywords: ${chalk.yellow(info.keywords.join(', '))}`) + if (bins.length) { + output.standard(`\nbin: ${chalk.cyan(bins.join(', '))}`) } - if (info.bins.length) { - this.npm.output('') - this.npm.output(`bin: ${chalk.yellow(info.bins.join(', '))}`) + output.standard('\ndist') + output.standard(`.tarball: ${chalk.blue(manifest.dist.tarball)}`) + output.standard(`.shasum: ${chalk.green(manifest.dist.shasum)}`) + if (manifest.dist.integrity) { + output.standard(`.integrity: ${chalk.green(manifest.dist.integrity)}`) + } + if (manifest.dist.unpackedSize) { + output.standard(`.unpackedSize: ${chalk.blue(formatBytes(manifest.dist.unpackedSize, true))}`) } - this.npm.output('') - this.npm.output('dist') - this.npm.output(`.tarball: ${info.tarball}`) - this.npm.output(`.shasum: ${info.shasum}`) - info.integrity && this.npm.output(`.integrity: ${info.integrity}`) - info.unpackedSize && this.npm.output(`.unpackedSize: ${info.unpackedSize}`) - - const maxDeps = 24 - if (info.deps.length) { - this.npm.output('') - this.npm.output('dependencies:') - this.npm.output(columns(info.deps.slice(0, maxDeps), { padding: 1 })) - if (info.deps.length > maxDeps) { - this.npm.output(`(...and ${info.deps.length - maxDeps} more.)`) + if (deps.length) { + const maxDeps = 24 + output.standard('\ndependencies:') + output.standard(columns(deps.slice(0, maxDeps), { padding: 1 })) + if (deps.length > maxDeps) { + output.standard(chalk.dim(`(...and ${deps.length - maxDeps} more.)`)) } } - if (info.maintainers && info.maintainers.length) { - this.npm.output('') - this.npm.output('maintainers:') - info.maintainers.forEach((u) => this.npm.output(`- ${u}`)) + if (packu.maintainers?.length) { + output.standard('\nmaintainers:') + packu.maintainers.forEach(u => + output.standard(`- ${unparsePerson({ + name: chalk.blue(u.name), + email: chalk.dim(u.email) })}`) + ) } - this.npm.output('') - this.npm.output('dist-tags:') - this.npm.output(columns(info.tags)) + output.standard('\ndist-tags:') + output.standard(columns(Object.keys(packu['dist-tags']).map(t => + `${chalk.blue(t)}: ${packu['dist-tags'][t]}` + ))) - if (info.publisher || info.modified) { + const publisher = manifest._npmUser && unparsePerson({ + name: chalk.blue(manifest._npmUser.name), + email: chalk.dim(manifest._npmUser.email), + }) + if (publisher || packu.time) { let publishInfo = 'published' - if (info.modified) { - publishInfo += ` ${info.modified}` + if (packu.time) { + publishInfo += ` ${chalk.cyan(relativeDate(packu.time[manifest.version]))}` } - if (info.publisher) { - publishInfo += ` by ${info.publisher}` + if (publisher) { + publishInfo += ` by ${publisher}` } - this.npm.output('') - this.npm.output(publishInfo) + output.standard('') + output.standard(publishInfo) } } } + module.exports = View function cleanBlanks (obj) { diff --git a/deps/npm/lib/commands/whoami.js b/deps/npm/lib/commands/whoami.js index 154cc870391ba1..507adb276c7313 100644 --- a/deps/npm/lib/commands/whoami.js +++ b/deps/npm/lib/commands/whoami.js @@ -1,16 +1,18 @@ +const { output } = require('proc-log') const getIdentity = require('../utils/get-identity.js') +const BaseCommand = require('../base-cmd.js') -const BaseCommand = require('../base-command.js') class Whoami extends BaseCommand { static description = 'Display npm username' static name = 'whoami' static params = ['registry'] - async exec (args) { + async exec () { const username = await getIdentity(this.npm, { ...this.npm.flatOptions }) - this.npm.output( + output.standard( this.npm.config.get('json') ? JSON.stringify(username) : username ) } } + module.exports = Whoami diff --git a/deps/npm/lib/lifecycle-cmd.js b/deps/npm/lib/lifecycle-cmd.js index 848771a38355e5..a509a9380f668c 100644 --- a/deps/npm/lib/lifecycle-cmd.js +++ b/deps/npm/lib/lifecycle-cmd.js @@ -1,7 +1,7 @@ +const BaseCommand = require('./base-cmd.js') + // The implementation of commands that are just "run a script" // restart, start, stop, test - -const BaseCommand = require('./base-command.js') class LifecycleCmd extends BaseCommand { static usage = ['[-- ]'] static isShellout = true @@ -16,4 +16,5 @@ class LifecycleCmd extends BaseCommand { return this.npm.exec('run-script', [this.constructor.name, ...args]) } } + module.exports = LifecycleCmd diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js index d05b74ac74b833..df2297b215da7b 100644 --- a/deps/npm/lib/npm.js +++ b/deps/npm/lib/npm.js @@ -1,19 +1,14 @@ -const { resolve, dirname, join } = require('path') +const { resolve, dirname, join } = require('node:path') const Config = require('@npmcli/config') const which = require('which') -const fs = require('fs/promises') - -// Patch the global fs module here at the app level -require('graceful-fs').gracefulify(require('fs')) - +const fs = require('node:fs/promises') const { definitions, flatten, shorthands } = require('@npmcli/config/lib/definitions') const usage = require('./utils/npm-usage.js') const LogFile = require('./utils/log-file.js') const Timers = require('./utils/timers.js') const Display = require('./utils/display.js') -const log = require('./utils/log-shim') +const { log, time, output } = require('proc-log') const { redactLog: replaceInfo } = require('@npmcli/redact') -const updateNotifier = require('./utils/update-notifier.js') const pkg = require('../package.json') const { deref } = require('./utils/cmd-list.js') @@ -27,38 +22,25 @@ class Npm { if (!command) { throw Object.assign(new Error(`Unknown command ${c}`), { code: 'EUNKNOWNCOMMAND', + command: c, }) } return require(`./commands/${command}.js`) } + unrefPromises = [] updateNotification = null - loadErr = null argv = [] #command = null #runId = new Date().toISOString().replace(/[.:]/g, '_') - #loadPromise = null #title = 'npm' #argvClean = [] #npmRoot = null - #warnedNonDashArg = false - - #chalk = null - #logChalk = null - #noColorChalk = null - #outputBuffer = [] + #display = null #logFile = new LogFile() - #display = new Display() - #timers = new Timers({ - start: 'npm', - listener: (name, ms) => { - const args = ['timing', name, `Completed in ${ms}ms`] - this.#logFile.log(...args) - this.#display.log(...args) - }, - }) + #timers = new Timers() // all these options are only used by tests in order to make testing more // closely resemble real world usage. for now, npm has no programmatic API so @@ -72,7 +54,14 @@ class Npm { // allows tests created by tap inside this repo to not set the local // prefix to `npmRoot` since that is the first dir it would encounter when // doing implicit detection - constructor ({ npmRoot = dirname(__dirname), argv = [], excludeNpmCwd = false } = {}) { + constructor ({ + stdout = process.stdout, + stderr = process.stderr, + npmRoot = dirname(__dirname), + argv = [], + excludeNpmCwd = false, + } = {}) { + this.#display = new Display({ stdout, stderr }) this.#npmRoot = npmRoot this.config = new Config({ npmPath: this.#npmRoot, @@ -88,7 +77,8 @@ class Npm { return this.constructor.version } - setCmd (cmd) { + // Call an npm command + async exec (cmd, args = this.argv) { const Command = Npm.cmd(cmd) const command = new Command(this) @@ -99,51 +89,11 @@ class Npm { process.env.npm_command = this.command } - return command - } - - // Call an npm command - // TODO: tests are currently the only time the second - // parameter of args is used. When called via `lib/cli.js` the config is - // loaded and this.argv is set to the remaining command line args. We should - // consider testing the CLI the same way it is used and not allow args to be - // passed in directly. - async exec (cmd, args = this.argv) { - const command = this.setCmd(cmd) - - const timeEnd = this.time(`command:${cmd}`) - - // this is async but we dont await it, since its ok if it doesnt - // finish before the command finishes running. it uses command and argv - // so it must be initiated here, after the command name is set - // eslint-disable-next-line promise/catch-or-return - updateNotifier(this).then((msg) => (this.updateNotification = msg)) - - // Options are prefixed by a hyphen-minus (-, \u2d). - // Other dash-type chars look similar but are invalid. - if (!this.#warnedNonDashArg) { - const nonDashArgs = args.filter(a => /^[\u2010-\u2015\u2212\uFE58\uFE63\uFF0D]/.test(a)) - if (nonDashArgs.length) { - this.#warnedNonDashArg = true - log.error( - 'arg', - 'Argument starts with non-ascii dash, this is probably invalid:', - nonDashArgs.join(', ') - ) - } - } - - return command.cmdExec(args).finally(timeEnd) + return time.start(`command:${cmd}`, () => command.cmdExec(args)) } async load () { - if (!this.#loadPromise) { - this.#loadPromise = this.time('npm:load', () => this.#load().catch((er) => { - this.loadErr = er - throw er - })) - } - return this.#loadPromise + return time.start('npm:load', () => this.#load()) } get loaded () { @@ -159,30 +109,44 @@ class Npm { this.#logFile.off() } - time (name, fn) { - return this.#timers.time(name, fn) - } - - writeTimingFile () { - this.#timers.writeFile({ + finish ({ showLogFileError } = {}) { + this.#timers.finish({ id: this.#runId, command: this.#argvClean, logfiles: this.logFiles, version: this.version, }) + + if (showLogFileError) { + if (!this.silent) { + // just a line break if not in silent mode + output.error('') + } + + if (this.logFiles.length) { + return log.error('', `A complete log of this run can be found in: ${this.logFiles}`) + } + + const logsMax = this.config.get('logs-max') + if (logsMax <= 0) { + // user specified no log file + log.error('', `Log files were not written due to the config logs-max=${logsMax}`) + } else { + // could be an error writing to the directory + log.error('', + `Log files were not written due to an error writing to the directory: ${this.#logsDir}` + + '\nYou can rerun the command with `--loglevel=verbose` to see the logs in your terminal' + ) + } + } } get title () { return this.#title } - set title (t) { - process.title = t - this.#title = t - } - async #load () { - await this.time('npm:load:whichnode', async () => { + await time.start('npm:load:whichnode', async () => { // TODO should we throw here? const node = await which(process.argv[0]).catch(() => {}) if (node && node.toUpperCase() !== process.execPath.toUpperCase()) { @@ -192,46 +156,72 @@ class Npm { } }) - await this.time('npm:load:configload', () => this.config.load()) - - // get createSupportsColor from chalk directly if this lands - // https://github.com/chalk/chalk/pull/600 - const [{ Chalk }, { createSupportsColor }] = await Promise.all([ - import('chalk'), - import('supports-color'), - ]) - this.#noColorChalk = new Chalk({ level: 0 }) - // we get the chalk level based on a null stream meaning chalk will only use - // what it knows about the environment to get color support since we already - // determined in our definitions that we want to show colors. - const level = Math.max(createSupportsColor(null).level, 1) - this.#chalk = this.color ? new Chalk({ level }) : this.#noColorChalk - this.#logChalk = this.logColor ? new Chalk({ level }) : this.#noColorChalk + await time.start('npm:load:configload', () => this.config.load()) + + // npm --versions + if (this.config.get('versions', 'cli')) { + this.argv = ['version'] + this.config.set('usage', false, 'cli') + } else { + this.argv = [...this.config.parsedArgv.remain] + } + + // Remove first argv since that is our command as typed + // Note that this might not be the actual name of the command + // due to aliases, etc. But we use the raw form of it later + // in user output so it must be preserved as is. + const commandArg = this.argv.shift() + + // This is the actual name of the command that will be run or + // undefined if deref could not find a match + const command = deref(commandArg) + + await this.#display.load({ + command, + loglevel: this.config.get('loglevel'), + stdoutColor: this.color, + stderrColor: this.logColor, + timing: this.config.get('timing'), + unicode: this.config.get('unicode'), + progress: this.flatOptions.progress, + json: this.config.get('json'), + heading: this.config.get('heading'), + }) + process.env.COLOR = this.color ? '1' : '0' + + // npm -v + // return from here early so we dont create any caches/logfiles/timers etc + if (this.config.get('version', 'cli')) { + output.standard(this.version) + return { exec: false } + } // mkdir this separately since the logs dir can be set to // a different location. if this fails, then we don't have // a cache dir, but we don't want to fail immediately since // the command might not need a cache dir (like `npm --version`) - await this.time('npm:load:mkdirpcache', () => + await time.start('npm:load:mkdirpcache', () => fs.mkdir(this.cache, { recursive: true }) .catch((e) => log.verbose('cache', `could not create cache: ${e}`))) // it's ok if this fails. user might have specified an invalid dir // which we will tell them about at the end if (this.config.get('logs-max') > 0) { - await this.time('npm:load:mkdirplogs', () => - fs.mkdir(this.logsDir, { recursive: true }) + await time.start('npm:load:mkdirplogs', () => + fs.mkdir(this.#logsDir, { recursive: true }) .catch((e) => log.verbose('logfile', `could not create logs-dir: ${e}`))) } // note: this MUST be shorter than the actual argv length, because it // uses the same memory, so node will truncate it if it's too long. - this.time('npm:load:setTitle', () => { + // We time this because setting process.title is slow sometimes but we + // have to do it for security reasons. But still helpful to know how slow it is. + time.start('npm:load:setTitle', () => { const { parsedArgv: { cooked, remain } } = this.config - this.argv = remain // Secrets are mostly in configs, so title is set using only the positional args - // to keep those from being leaked. - this.title = ['npm'].concat(replaceInfo(remain)).join(' ').trim() + // to keep those from being leaked. We still do a best effort replaceInfo. + this.#title = ['npm'].concat(replaceInfo(remain)).join(' ').trim() + process.title = this.#title // The cooked argv is also logged separately for debugging purposes. It is // cleaned as a best effort by replacing known secrets like basic auth // password and strings that look like npm tokens. XXX: for this to be @@ -242,45 +232,32 @@ class Npm { log.verbose('argv', this.#argvClean.map(JSON.stringify).join(' ')) }) - this.time('npm:load:display', () => { - this.#display.load({ - // Use logColor since that is based on stderr - color: this.logColor, - chalk: this.logChalk, - progress: this.flatOptions.progress, - silent: this.silent, - timing: this.config.get('timing'), - loglevel: this.config.get('loglevel'), - unicode: this.config.get('unicode'), - heading: this.config.get('heading'), - }) - process.env.COLOR = this.color ? '1' : '0' - }) - - this.time('npm:load:logFile', () => { - this.#logFile.load({ - path: this.logPath, - logsMax: this.config.get('logs-max'), - }) - log.verbose('logfile', this.#logFile.files[0] || 'no logfile created') + // logFile.load returns a promise that resolves when old logs are done being cleaned. + // We save this promise to an array so that we can await it in tests to ensure more + // deterministic logging behavior. The process will also hang open if this were to + // take a long time to resolve, but that is why process.exit is called explicitly + // in the exit-handler. + this.unrefPromises.push(this.#logFile.load({ + path: this.logPath, + logsMax: this.config.get('logs-max'), + timing: this.config.get('timing'), + })) + + this.#timers.load({ + path: this.logPath, + timing: this.config.get('timing'), }) - this.time('npm:load:timers', () => - this.#timers.load({ - path: this.config.get('timing') ? this.logPath : null, - }) - ) - - this.time('npm:load:configScope', () => { - const configScope = this.config.get('scope') - if (configScope && !/^@/.test(configScope)) { - this.config.set('scope', `@${configScope}`, this.config.find('scope')) - } - }) + const configScope = this.config.get('scope') + if (configScope && !/^@/.test(configScope)) { + this.config.set('scope', `@${configScope}`, this.config.find('scope')) + } if (this.config.get('force')) { log.warn('using --force', 'Recommended protections disabled.') } + + return { exec: true, command: commandArg, args: this.argv } } get isShellout () { @@ -313,15 +290,15 @@ class Npm { } get noColorChalk () { - return this.#noColorChalk + return this.#display.chalk.noColor } get chalk () { - return this.#chalk + return this.#display.chalk.stdout } get logChalk () { - return this.#logChalk + return this.#display.chalk.stderr } get global () { @@ -336,14 +313,6 @@ class Npm { return 2 } - get unfinishedTimers () { - return this.#timers.unfinished - } - - get finishedTimers () { - return this.#timers.finished - } - get started () { return this.#timers.started } @@ -352,16 +321,12 @@ class Npm { return this.#logFile.files } - get logsDir () { + get #logsDir () { return this.config.get('logs-dir') || join(this.cache, '_logs') } get logPath () { - return resolve(this.logsDir, `${this.#runId}-`) - } - - get timingFile () { - return this.#timers.file + return resolve(this.#logsDir, `${this.#runId}-`) } get npmRoot () { @@ -372,26 +337,14 @@ class Npm { return this.config.get('cache') } - set cache (r) { - this.config.set('cache', r) - } - get globalPrefix () { return this.config.globalPrefix } - set globalPrefix (r) { - this.config.globalPrefix = r - } - get localPrefix () { return this.config.localPrefix } - set localPrefix (r) { - this.config.localPrefix = r - } - get localPackage () { return this.config.localPackage } @@ -427,59 +380,9 @@ class Npm { return this.global ? this.globalPrefix : this.localPrefix } - set prefix (r) { - const k = this.global ? 'globalPrefix' : 'localPrefix' - this[k] = r - } - get usage () { return usage(this) } - - // output to stdout in a progress bar compatible way - output (...msg) { - log.clearProgress() - // eslint-disable-next-line no-console - console.log(...msg.map(Display.clean)) - log.showProgress() - } - - outputBuffer (item) { - this.#outputBuffer.push(item) - } - - flushOutput (jsonError) { - if (!jsonError && !this.#outputBuffer.length) { - return - } - - if (this.config.get('json')) { - const jsonOutput = this.#outputBuffer.reduce((acc, item) => { - if (typeof item === 'string') { - // try to parse it as json in case its a string - try { - item = JSON.parse(item) - } catch { - return acc - } - } - return { ...acc, ...item } - }, {}) - this.output(JSON.stringify({ ...jsonOutput, ...jsonError }, null, 2)) - } else { - for (const item of this.#outputBuffer) { - this.output(item) - } - } - - this.#outputBuffer.length = 0 - } - - outputError (...msg) { - log.clearProgress() - // eslint-disable-next-line no-console - console.error(...msg.map(Display.clean)) - log.showProgress() - } } + module.exports = Npm diff --git a/deps/npm/lib/package-url-cmd.js b/deps/npm/lib/package-url-cmd.js index 250b46eeeddbe5..bcefd17af4492a 100644 --- a/deps/npm/lib/package-url-cmd.js +++ b/deps/npm/lib/package-url-cmd.js @@ -1,12 +1,9 @@ -// Base command for opening urls from a package manifest (bugs, docs, repo) - const pacote = require('pacote') -const hostedGitInfo = require('hosted-git-info') - const openUrl = require('./utils/open-url.js') -const log = require('./utils/log-shim') +const { log } = require('proc-log') +const BaseCommand = require('./base-cmd.js') -const BaseCommand = require('./base-command.js') +// Base command for opening urls from a package manifest (bugs, docs, repo) class PackageUrlCommand extends BaseCommand { static params = [ 'browser', @@ -52,6 +49,7 @@ class PackageUrlCommand extends BaseCommand { // repository (if a string) or repository.url (if an object) returns null // if it's not a valid repo, or not a known hosted repo hostedFromMani (mani) { + const hostedGitInfo = require('hosted-git-info') const r = mani.repository const rurl = !r ? null : typeof r === 'string' ? r @@ -62,4 +60,5 @@ class PackageUrlCommand extends BaseCommand { return (rurl && hostedGitInfo.fromUrl(rurl.replace(/^git\+/, ''))) || null } } + module.exports = PackageUrlCommand diff --git a/deps/npm/lib/utils/audit-error.js b/deps/npm/lib/utils/audit-error.js index f9850d718b198e..10aec7592b03ce 100644 --- a/deps/npm/lib/utils/audit-error.js +++ b/deps/npm/lib/utils/audit-error.js @@ -1,4 +1,4 @@ -const log = require('./log-shim') +const { log, output } = require('proc-log') const { redactLog: replaceInfo } = require('@npmcli/redact') // print an error or just nothing if the audit report has an error @@ -22,7 +22,7 @@ const auditError = (npm, report) => { const { body: errBody } = error const body = Buffer.isBuffer(errBody) ? errBody.toString() : errBody if (npm.flatOptions.json) { - npm.output(JSON.stringify({ + output.standard(JSON.stringify({ message: error.message, method: error.method, uri: replaceInfo(error.uri), @@ -31,7 +31,7 @@ const auditError = (npm, report) => { body, }, null, 2)) } else { - npm.output(body) + output.standard(body) } throw 'audit endpoint returned an error' diff --git a/deps/npm/lib/utils/auth.js b/deps/npm/lib/utils/auth.js index 729ce32c2a7a8f..04ca455ceb5261 100644 --- a/deps/npm/lib/utils/auth.js +++ b/deps/npm/lib/utils/auth.js @@ -1,5 +1,5 @@ const profile = require('npm-profile') -const log = require('../utils/log-shim') +const { log } = require('proc-log') const openUrlPrompt = require('../utils/open-url-prompt.js') const read = require('../utils/read-user-info.js') const otplease = require('../utils/otplease.js') @@ -36,7 +36,7 @@ const adduser = async (npm, { creds, ...opts }) => { // password, it's effectively a login, and if that account has otp you'll // be prompted for it. res = await otplease(npm, opts, (reqOpts) => - profile.adduserCouch(username, email, password, opts) + profile.adduserCouch(username, email, password, reqOpts) ) } diff --git a/deps/npm/lib/utils/did-you-mean.js b/deps/npm/lib/utils/did-you-mean.js index ff3c812b46c3c7..54c8ff2e35aa69 100644 --- a/deps/npm/lib/utils/did-you-mean.js +++ b/deps/npm/lib/utils/did-you-mean.js @@ -8,7 +8,7 @@ const didYouMean = async (path, scmd) => { let best = [] for (const str of close) { const cmd = Npm.cmd(str) - best.push(` npm ${str} # ${cmd.description}`) + best.push(` npm ${str} # ${cmd.description}`) } // We would already be suggesting this in `npm x` so omit them here const runScripts = ['stop', 'start', 'test', 'restart'] @@ -17,13 +17,13 @@ const didYouMean = async (path, scmd) => { best = best.concat( Object.keys(scripts || {}) .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && !runScripts.includes(cmd)) - .map(str => ` npm run ${str} # run the "${str}" package script`), + .map(str => ` npm run ${str} # run the "${str}" package script`), Object.keys(bin || {}) .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4) /* eslint-disable-next-line max-len */ - .map(str => ` npm exec ${str} # run the "${str}" command from either this or a remote npm package`) + .map(str => ` npm exec ${str} # run the "${str}" command from either this or a remote npm package`) ) - } catch (_) { + } catch { // gracefully ignore not being in a folder w/ a package.json } @@ -31,10 +31,9 @@ const didYouMean = async (path, scmd) => { return '' } - const suggestion = - best.length === 1 - ? `\n\nDid you mean this?\n${best[0]}` - : `\n\nDid you mean one of these?\n${best.slice(0, 3).join('\n')}` - return suggestion + return best.length === 1 + ? `\n\nDid you mean this?\n${best[0]}` + : `\n\nDid you mean one of these?\n${best.slice(0, 3).join('\n')}` } + module.exports = didYouMean diff --git a/deps/npm/lib/utils/display.js b/deps/npm/lib/utils/display.js index c5e5ca2b5b874a..29a1f7951d5063 100644 --- a/deps/npm/lib/utils/display.js +++ b/deps/npm/lib/utils/display.js @@ -1,214 +1,489 @@ -const { inspect } = require('util') -const npmlog = require('npmlog') -const log = require('./log-shim.js') +const { log, output, input, META } = require('proc-log') const { explain } = require('./explain-eresolve.js') +const { formatWithOptions } = require('./format') -const originalCustomInspect = Symbol('npm.display.original.util.inspect.custom') - -// These are most assuredly not a mistake -// https://eslint.org/docs/latest/rules/no-control-regex -/* eslint-disable no-control-regex */ -// \x00 through \x1f, \x7f through \x9f, not including \x09 \x0a \x0b \x0d -const hasC01 = /[\x00-\x08\x0c\x0e-\x1f\x7f-\x9f]/ -// Allows everything up to '[38;5;255m' in 8 bit notation -const allowedSGR = /^\[[0-9;]{0,8}m/ -// '[38;5;255m'.length -const sgrMaxLen = 10 - -// Strips all ANSI C0 and C1 control characters (except for SGR up to 8 bit) -function stripC01 (str) { - if (!hasC01.test(str)) { - return str - } - let result = '' - for (let i = 0; i < str.length; i++) { - const char = str[i] - const code = char.charCodeAt(0) - if (!hasC01.test(char)) { - // Most characters are in this set so continue early if we can - result = `${result}${char}` - } else if (code === 27 && allowedSGR.test(str.slice(i + 1, i + sgrMaxLen + 1))) { - // \x1b with allowed SGR - result = `${result}\x1b` - } else if (code <= 31) { - // escape all other C0 control characters besides \x7f - result = `${result}^${String.fromCharCode(code + 64)}` - } else { - // hasC01 ensures this is now a C1 control character or \x7f - result = `${result}^${String.fromCharCode(code - 64)}` +// This is the general approach to color: +// Eventually this will be exposed somewhere we can refer to these by name. +// Foreground colors only. Never set the background color. +/* + * Black # (Don't use) + * Red # Danger + * Green # Success + * Yellow # Warning + * Blue # Accent + * Magenta # Done + * Cyan # Emphasis + * White # (Don't use) + */ + +// Translates log levels to chalk colors +const COLOR_PALETTE = ({ chalk: c }) => ({ + heading: c.bold, + title: c.blueBright, + timing: c.magentaBright, + // loglevels + error: c.red, + warn: c.yellow, + notice: c.cyanBright, + http: c.green, + info: c.cyan, + verbose: c.blue, + silly: c.blue.dim, +}) + +const LEVEL_OPTIONS = { + silent: { + index: 0, + }, + error: { + index: 1, + }, + warn: { + index: 2, + }, + notice: { + index: 3, + }, + http: { + index: 4, + }, + info: { + index: 5, + }, + verbose: { + index: 6, + }, + silly: { + index: 7, + }, +} + +const LEVEL_METHODS = { + ...LEVEL_OPTIONS, + [log.KEYS.timing]: { + show: ({ timing, index }) => !!timing && index !== 0, + }, +} + +const tryJsonParse = (value) => { + if (typeof value === 'string') { + try { + return JSON.parse(value) + } catch { + return {} } } - return result + return value } -class Display { - #chalk = null +const setBlocking = (stream) => { + // Copied from https://github.com/yargs/set-blocking + // https://raw.githubusercontent.com/yargs/set-blocking/master/LICENSE.txt + /* istanbul ignore next - we trust that this works */ + if (stream._handle && stream.isTTY && typeof stream._handle.setBlocking === 'function') { + stream._handle.setBlocking(true) + } + return stream +} + +const withMeta = (handler) => (level, ...args) => { + let meta = {} + const last = args.at(-1) + if (last && typeof last === 'object' && Object.hasOwn(last, META)) { + meta = args.pop() + } + return handler(level, meta, ...args) +} - constructor () { - // pause by default until config is loaded - this.on() - log.pause() +class Display { + #logState = { + buffering: true, + buffer: [], } - static clean (output) { - if (typeof output === 'string') { - // Strings are cleaned inline - return stripC01(output) - } - if (!output || typeof output !== 'object') { - // Numbers, booleans, null all end up here and don't need cleaning - return output - } - // output && typeof output === 'object' - // We can't use hasOwn et al for detecting the original but we can use it - // for detecting the properties we set via defineProperty - if ( - output[inspect.custom] && - (!Object.hasOwn(output, originalCustomInspect)) - ) { - // Save the old one if we didn't already do it. - Object.defineProperty(output, originalCustomInspect, { - value: output[inspect.custom], - writable: true, - }) - } - if (!Object.hasOwn(output, originalCustomInspect)) { - // Put a dummy one in for when we run multiple times on the same object - Object.defineProperty(output, originalCustomInspect, { - value: function () { - return this - }, - writable: true, - }) - } - // Set the custom inspect to our own function - Object.defineProperty(output, inspect.custom, { - value: function () { - const toClean = this[originalCustomInspect]() - // Custom inspect can return things other than objects, check type again - if (typeof toClean === 'string') { - // Strings are cleaned inline - return stripC01(toClean) - } - if (!toClean || typeof toClean !== 'object') { - // Numbers, booleans, null all end up here and don't need cleaning - return toClean - } - return stripC01(inspect(toClean, { customInspect: false })) - }, - writable: true, - }) - return output + #outputState = { + buffering: true, + buffer: [], } - on () { + // colors + #noColorChalk + #stdoutChalk + #stdoutColor + #stderrChalk + #stderrColor + #logColors + + // progress + #progress + + // options + #command + #levelIndex + #timing + #json + #heading + #silent + + // display streams + #stdout + #stderr + + constructor ({ stdout, stderr }) { + this.#stdout = setBlocking(stdout) + this.#stderr = setBlocking(stderr) + + // Handlers are set immediately so they can buffer all events process.on('log', this.#logHandler) + process.on('output', this.#outputHandler) + process.on('input', this.#inputHandler) + this.#progress = new Progress({ stream: stderr }) } off () { process.off('log', this.#logHandler) - // Unbalanced calls to enable/disable progress - // will leave change listeners on the tracker - // This pretty much only happens in tests but - // this removes the event emitter listener warnings - log.tracker.removeAllListeners() - } - - load (config) { - const { - color, - chalk, - timing, - loglevel, + this.#logState.buffer.length = 0 + process.off('output', this.#outputHandler) + this.#outputState.buffer.length = 0 + process.off('input', this.#inputHandler) + this.#progress.off() + } + + get chalk () { + return { + noColor: this.#noColorChalk, + stdout: this.#stdoutChalk, + stderr: this.#stderrChalk, + } + } + + async load ({ + command, + heading, + json, + loglevel, + progress, + stderrColor, + stdoutColor, + timing, + unicode, + }) { + // get createSupportsColor from chalk directly if this lands + // https://github.com/chalk/chalk/pull/600 + const [{ Chalk }, { createSupportsColor }] = await Promise.all([ + import('chalk'), + import('supports-color'), + ]) + // we get the chalk level based on a null stream meaning chalk will only use + // what it knows about the environment to get color support since we already + // determined in our definitions that we want to show colors. + const level = Math.max(createSupportsColor(null).level, 1) + this.#noColorChalk = new Chalk({ level: 0 }) + this.#stdoutColor = stdoutColor + this.#stdoutChalk = stdoutColor ? new Chalk({ level }) : this.#noColorChalk + this.#stderrColor = stderrColor + this.#stderrChalk = stderrColor ? new Chalk({ level }) : this.#noColorChalk + this.#logColors = COLOR_PALETTE({ chalk: this.#stderrChalk }) + + this.#command = command + this.#levelIndex = LEVEL_OPTIONS[loglevel].index + this.#timing = timing + this.#json = json + this.#heading = heading + this.#silent = this.#levelIndex <= 0 + + // Emit resume event on the logs which will flush output + log.resume() + output.flush() + this.#progress.load({ unicode, - progress, - silent, - heading = 'npm', - } = config - - this.#chalk = chalk - - // npmlog is still going away someday, so this is a hack to dynamically - // set the loglevel of timing based on the timing flag, instead of making - // a breaking change to npmlog. The result is that timing logs are never - // shown except when the --timing flag is set. We also need to change - // the index of the silly level since otherwise it is set to -Infinity - // and we can't go any lower than that. silent is still set to Infinify - // because we DO want silent to hide timing levels. This allows for the - // special case of getting timing information while hiding all CLI output - // in order to get perf information that might be affected by writing to - // a terminal. XXX(npmlog): this will be removed along with npmlog - log.levels.silly = -10000 - log.levels.timing = log.levels[loglevel] + (timing ? 1 : -1) - - log.level = loglevel - log.heading = heading - - if (color) { - log.enableColor() - } else { - log.disableColor() + enabled: !!progress && !this.#silent, + }) + } + + // STREAM WRITES + + // Write formatted and (non-)colorized output to streams + #write (stream, options, ...args) { + const colors = stream === this.#stdout ? this.#stdoutColor : this.#stderrColor + const value = formatWithOptions({ colors, ...options }, ...args) + this.#progress.write(() => stream.write(value)) + } + + // HANDLERS + + // Arrow function assigned to a private class field so it can be passed + // directly as a listener and still reference "this" + #logHandler = withMeta((level, meta, ...args) => { + switch (level) { + case log.KEYS.resume: + this.#logState.buffering = false + this.#logState.buffer.forEach((item) => this.#tryWriteLog(...item)) + this.#logState.buffer.length = 0 + break + + case log.KEYS.pause: + this.#logState.buffering = true + break + + default: + if (this.#logState.buffering) { + this.#logState.buffer.push([level, meta, ...args]) + } else { + this.#tryWriteLog(level, meta, ...args) + } + break } + }) - if (unicode) { - log.enableUnicode() - } else { - log.disableUnicode() + // Arrow function assigned to a private class field so it can be passed + // directly as a listener and still reference "this" + #outputHandler = withMeta((level, meta, ...args) => { + switch (level) { + case output.KEYS.flush: + this.#outputState.buffering = false + if (meta.jsonError && this.#json) { + const json = {} + for (const item of this.#outputState.buffer) { + // index 2 skips the level and meta + Object.assign(json, tryJsonParse(item[2])) + } + this.#writeOutput( + output.KEYS.standard, + meta, + JSON.stringify({ ...json, error: meta.jsonError }, null, 2) + ) + } else { + this.#outputState.buffer.forEach((item) => this.#writeOutput(...item)) + } + this.#outputState.buffer.length = 0 + break + + case output.KEYS.buffer: + this.#outputState.buffer.push([output.KEYS.standard, meta, ...args]) + break + + default: + if (this.#outputState.buffering) { + this.#outputState.buffer.push([level, meta, ...args]) + } else { + // HACK: Check if the argument looks like a run-script banner. This can be + // replaced with proc-log.META in @npmcli/run-script + if (typeof args[0] === 'string' && args[0].startsWith('\n> ') && args[0].endsWith('\n')) { + if (this.#silent || ['exec', 'explore'].includes(this.#command)) { + // Silent mode and some specific commands always hide run script banners + break + } else if (this.#json) { + // In json mode, change output to stderr since we dont want to break json + // parsing on stdout if the user is piping to jq or something. + // XXX: in a future (breaking?) change it might make sense for run-script to + // always output these banners with proc-log.output.error if we think they + // align closer with "logging" instead of "output" + level = output.KEYS.error + } + } + this.#writeOutput(level, meta, ...args) + } + break } + }) - // if it's silent, don't show progress - if (progress && !silent) { - log.enableProgress() - } else { - log.disableProgress() + #inputHandler = withMeta((level, meta, ...args) => { + switch (level) { + case input.KEYS.start: + log.pause() + this.#outputState.buffering = true + this.#progress.off() + break + + case input.KEYS.end: + log.resume() + output.flush() + this.#progress.resume() + break + + case input.KEYS.read: { + // The convention when calling input.read is to pass in a single fn that returns + // the promise to await. resolve and reject are provided by proc-log + const [res, rej, p] = args + return input.start(() => p() + .then(res) + .catch(rej) + // Any call to procLog.input.read will render a prompt to the user, so we always + // add a single newline of output to stdout to move the cursor to the next line + .finally(() => output.standard(''))) + } } + }) - // Resume displaying logs now that we have config - log.resume() - } + // OUTPUT + + #writeOutput (level, meta, ...args) { + switch (level) { + case output.KEYS.standard: + this.#write(this.#stdout, {}, ...args) + break - log (...args) { - this.#logHandler(...args) + case output.KEYS.error: + this.#write(this.#stderr, {}, ...args) + break + } } - #logHandler = (level, ...args) => { + // LOGS + + #tryWriteLog (level, meta, ...args) { try { - this.#log(level, ...args) + // Also (and this is a really inexcusable kludge), we patch the + // log.warn() method so that when we see a peerDep override + // explanation from Arborist, we can replace the object with a + // highly abbreviated explanation of what's being overridden. + // TODO: this could probably be moved to arborist now that display is refactored + const [heading, message, expl] = args + if (level === log.KEYS.warn && heading === 'ERESOLVE' && expl && typeof expl === 'object') { + this.#writeLog(level, meta, heading, message) + this.#writeLog(level, meta, '', explain(expl, this.#stderrChalk, 2)) + return + } + this.#writeLog(level, meta, ...args) } catch (ex) { try { // if it crashed once, it might again! - this.#npmlog('verbose', `attempt to log ${inspect(args)} crashed`, ex) + this.#writeLog(log.KEYS.verbose, meta, '', `attempt to log crashed`, ...args, ex) } catch (ex2) { + // This happens if the object has an inspect method that crashes so just console.error + // with the errors but don't do anything else that might error again. // eslint-disable-next-line no-console - console.error(`attempt to log ${inspect(args)} crashed`, ex, ex2) + console.error(`attempt to log crashed`, ex, ex2) } } } - #log (...args) { - return this.#eresolveWarn(...args) || this.#npmlog(...args) + #writeLog (level, meta, ...args) { + const levelOpts = LEVEL_METHODS[level] + const show = levelOpts.show ?? (({ index }) => levelOpts.index <= index) + const force = meta.force && !this.#silent + + if (force || show({ index: this.#levelIndex, timing: this.#timing })) { + // this mutates the array so we can pass args directly to format later + const title = args.shift() + const prefix = [ + this.#logColors.heading(this.#heading), + this.#logColors[level](level), + title ? this.#logColors.title(title) : null, + ] + this.#write(this.#stderr, { prefix }, ...args) + } + } +} + +class Progress { + // Taken from https://github.com/sindresorhus/cli-spinners + // MIT License + // Copyright (c) Sindre Sorhus (https://sindresorhus.com) + static dots = { duration: 80, frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'] } + static lines = { duration: 130, frames: ['-', '\\', '|', '/'] } + + #stream + #spinner + #enabled = false + + #frameIndex = 0 + #lastUpdate = 0 + #interval + #timeout + + // We are rendering is enabled option is set and we are not waiting for the render timeout + get #rendering () { + return this.#enabled && !this.#timeout + } + + // We are spinning if enabled option is set and the render interval has been set + get #spinning () { + return this.#enabled && this.#interval + } + + constructor ({ stream }) { + this.#stream = stream + } + + load ({ enabled, unicode }) { + this.#enabled = enabled + this.#spinner = unicode ? Progress.dots : Progress.lines + // Dont render the spinner for short durations + this.#render(200) + } + + off () { + if (!this.#enabled) { + return + } + clearTimeout(this.#timeout) + this.#timeout = null + clearInterval(this.#interval) + this.#interval = null + this.#frameIndex = 0 + this.#lastUpdate = 0 + this.#clearSpinner() + } + + resume () { + this.#render() } - // Explicitly call these on npmlog and not log shim - // This is the final place we should call npmlog before removing it. - #npmlog (level, ...args) { - npmlog[level](...args.map(Display.clean)) + // If we are currenting rendering the spinner we clear it + // before writing our line and then re-render the spinner after. + // If not then all we need to do is write the line + write (write) { + if (this.#spinning) { + this.#clearSpinner() + } + write() + if (this.#spinning) { + this.#render() + } + } + + #render (ms) { + if (ms) { + this.#timeout = setTimeout(() => { + this.#timeout = null + this.#renderSpinner() + }, ms) + // Make sure this timeout does not keep the process open + this.#timeout.unref() + } else { + this.#renderSpinner() + } } - // Also (and this is a really inexcusable kludge), we patch the - // log.warn() method so that when we see a peerDep override - // explanation from Arborist, we can replace the object with a - // highly abbreviated explanation of what's being overridden. - #eresolveWarn (level, heading, message, expl) { - if (level === 'warn' && - heading === 'ERESOLVE' && - expl && typeof expl === 'object' - ) { - this.#npmlog(level, heading, message) - this.#npmlog(level, '', explain(expl, this.#chalk, 2)) - // Return true to short circuit other log in chain - return true + #renderSpinner () { + if (!this.#rendering) { + return } + // We always attempt to render immediately but we only request to move to the next + // frame if it has been longer than our spinner frame duration since our last update + this.#renderFrame(Date.now() - this.#lastUpdate >= this.#spinner.duration) + clearInterval(this.#interval) + this.#interval = setInterval(() => this.#renderFrame(true), this.#spinner.duration) + } + + #renderFrame (next) { + if (next) { + this.#lastUpdate = Date.now() + this.#frameIndex++ + if (this.#frameIndex >= this.#spinner.frames.length) { + this.#frameIndex = 0 + } + } + this.#clearSpinner() + this.#stream.write(this.#spinner.frames[this.#frameIndex]) + } + + #clearSpinner () { + // Move to the start of the line and clear the rest of the line + this.#stream.cursorTo(0) + this.#stream.clearLine(1) } } diff --git a/deps/npm/lib/utils/error-message.js b/deps/npm/lib/utils/error-message.js index 348bb63e2d5abd..969e56636dfe8d 100644 --- a/deps/npm/lib/utils/error-message.js +++ b/deps/npm/lib/utils/error-message.js @@ -1,19 +1,16 @@ -const { format } = require('util') -const { resolve } = require('path') +const { format } = require('node:util') +const { resolve } = require('node:path') const { redactLog: replaceInfo } = require('@npmcli/redact') -const { report } = require('./explain-eresolve.js') -const log = require('./log-shim') +const { log } = require('proc-log') const messageText = msg => msg.map(line => line.slice(1).join(' ')).join('\n') const jsonError = (er, npm, { summary, detail }) => { if (npm?.config.loaded && npm.config.get('json')) { return { - error: { - code: er.code, - summary: messageText(summary), - detail: messageText(detail), - }, + code: er.code, + summary: messageText(summary), + detail: messageText(detail), } } } @@ -32,6 +29,7 @@ const errorMessage = (er, npm) => { switch (er.code) { case 'ERESOLVE': { + const { report } = require('./explain-eresolve.js') short.push(['ERESOLVE', er.message]) detail.push(['', '']) // XXX(display): error messages are logged so we use the logColor since that is based @@ -77,9 +75,7 @@ const errorMessage = (er, npm) => { npm.config.loaded && er.dest.startsWith(npm.config.get('cache')) - const { isWindows } = require('./is-windows.js') - - if (!isWindows && (isCachePath || isCacheDest)) { + if (process.platform !== 'win32' && (isCachePath || isCacheDest)) { // user probably doesn't need this, but still add it to the debug log log.verbose(er.stack) short.push([ @@ -101,7 +97,7 @@ const errorMessage = (er, npm) => { '', [ '\nThe operation was rejected by your operating system.', - isWindows + process.platform === 'win32' /* eslint-disable-next-line max-len */ ? "It's possible that the file was already in use (by a text editor or antivirus),\n" + 'or that you lack permissions to access it.' diff --git a/deps/npm/lib/utils/explain-dep.js b/deps/npm/lib/utils/explain-dep.js index 86660d5d3ad4b0..4e9e93454e8a28 100644 --- a/deps/npm/lib/utils/explain-dep.js +++ b/deps/npm/lib/utils/explain-dep.js @@ -1,4 +1,4 @@ -const { relative } = require('path') +const { relative } = require('node:path') const explainNode = (node, depth, chalk) => printNode(node, chalk) + @@ -6,63 +6,32 @@ const explainNode = (node, depth, chalk) => explainLinksIn(node, depth, chalk) const colorType = (type, chalk) => { - const { red, yellow, cyan, magenta, blue, green, gray } = chalk - const style = type === 'extraneous' ? red - : type === 'dev' ? yellow - : type === 'optional' ? cyan - : type === 'peer' ? magenta - : type === 'bundled' ? blue - : type === 'workspace' ? green - : type === 'overridden' ? gray + const style = type === 'extraneous' ? chalk.red + : type === 'dev' ? chalk.blue + : type === 'optional' ? chalk.magenta + : type === 'peer' ? chalk.magentaBright + : type === 'bundled' ? chalk.underline.cyan + : type === 'workspace' ? chalk.blueBright + : type === 'overridden' ? chalk.dim : /* istanbul ignore next */ s => s return style(type) } const printNode = (node, chalk) => { - const { - name, - version, - location, - extraneous, - dev, - optional, - peer, - bundled, - isWorkspace, - overridden, - } = node - const { bold, dim, green } = chalk const extra = [] - if (extraneous) { - extra.push(' ' + bold(colorType('extraneous', chalk))) - } - - if (dev) { - extra.push(' ' + bold(colorType('dev', chalk))) - } - if (optional) { - extra.push(' ' + bold(colorType('optional', chalk))) - } - - if (peer) { - extra.push(' ' + bold(colorType('peer', chalk))) - } - - if (bundled) { - extra.push(' ' + bold(colorType('bundled', chalk))) - } - - if (overridden) { - extra.push(' ' + bold(colorType('overridden', chalk))) + for (const meta of ['extraneous', 'dev', 'optional', 'peer', 'bundled', 'overridden']) { + if (node[meta]) { + extra.push(` ${colorType(meta, chalk)}`) + } } - const pkgid = isWorkspace - ? green(`${name}@${version}`) - : `${bold(name)}@${bold(version)}` + const pkgid = node.isWorkspace + ? chalk.blueBright(`${node.name}@${node.version}`) + : `${node.name}@${node.version}` return `${pkgid}${extra.join('')}` + - (location ? dim(`\n${location}`) : '') + (node.location ? chalk.dim(`\n${node.location}`) : '') } const explainLinksIn = ({ linksIn }, depth, chalk) => { @@ -75,7 +44,7 @@ const explainLinksIn = ({ linksIn }, depth, chalk) => { return str.split('\n').join('\n ') } -const explainDependents = ({ name, dependents }, depth, chalk) => { +const explainDependents = ({ dependents }, depth, chalk) => { if (!dependents || !dependents.length || depth <= 0) { return '' } @@ -107,10 +76,9 @@ const explainDependents = ({ name, dependents }, depth, chalk) => { } const explainEdge = ({ name, type, bundled, from, spec, rawSpec, overridden }, depth, chalk) => { - const { bold } = chalk let dep = type === 'workspace' - ? bold(relative(from.location, spec.slice('file:'.length))) - : `${bold(name)}@"${bold(spec)}"` + ? chalk.bold(relative(from.location, spec.slice('file:'.length))) + : `${name}@"${spec}"` if (overridden) { dep = `${colorType('overridden', chalk)} ${dep} (was "${rawSpec}")` } diff --git a/deps/npm/lib/utils/format-search-stream.js b/deps/npm/lib/utils/format-search-stream.js index 046a4b1e20587b..b70bd915123da4 100644 --- a/deps/npm/lib/utils/format-search-stream.js +++ b/deps/npm/lib/utils/format-search-stream.js @@ -1,6 +1,6 @@ -const { stripVTControlCharacters } = require('node:util') +/* eslint-disable max-len */ +const { stripVTControlCharacters: strip } = require('node:util') const { Minipass } = require('minipass') -const columnify = require('columnify') // This module consumes package data in the following format: // @@ -16,14 +16,48 @@ const columnify = require('columnify') // The returned stream will format this package data // into a byte stream of formatted, displayable output. -module.exports = async (opts) => { - return opts.json ? new JSONOutputStream() : new TextOutputStream(opts) +function filter (data, exclude) { + const words = [data.name] + .concat(data.maintainers.map(m => m.username)) + .concat(data.keywords || []) + .map(f => f?.trim?.()) + .filter(Boolean) + .join(' ') + .toLowerCase() + + if (exclude.find(pattern => { + // Treats both /foo and /foo/ as regex searches + if (pattern.startsWith('/')) { + if (pattern.endsWith('/')) { + pattern = pattern.slice(0, -1) + } + return words.match(new RegExp(pattern.slice(1))) + } + return words.includes(pattern) + })) { + return false + } + + return true +} + +module.exports = (opts) => { + return opts.json ? new JSONOutputStream(opts) : new TextOutputStream(opts) } class JSONOutputStream extends Minipass { #didFirst = false + #exclude + + constructor (opts) { + super() + this.#exclude = opts.exclude + } write (obj) { + if (!filter(obj, this.#exclude)) { + return + } if (!this.#didFirst) { super.write('[\n') this.#didFirst = true @@ -41,94 +75,100 @@ class JSONOutputStream extends Minipass { } class TextOutputStream extends Minipass { - #opts - #line = 0 + #args + #chalk + #exclude + #parseable constructor (opts) { super() - this.#opts = opts + this.#args = opts.args.map(s => s.toLowerCase()).filter(Boolean) + this.#chalk = opts.npm.chalk + this.#exclude = opts.exclude + this.#parseable = opts.parseable } - write (pkg) { - return super.write(this.#prettify(pkg)) - } - - #prettify (data) { + write (data) { + if (!filter(data, this.#exclude)) { + return + } + // Normalize const pkg = { - author: data.maintainers.map((m) => `=${stripVTControlCharacters(m.username)}`).join(' '), - date: 'prehistoric', - description: stripVTControlCharacters(data.description ?? ''), - keywords: '', - name: stripVTControlCharacters(data.name), + authors: data.maintainers.map((m) => `${strip(m.username)}`).join(' '), + publisher: strip(data.publisher?.username || ''), + date: data.date ? data.date.toISOString().slice(0, 10) : 'prehistoric', + description: strip(data.description ?? ''), + keywords: [], + name: strip(data.name), version: data.version, } if (Array.isArray(data.keywords)) { - pkg.keywords = data.keywords.map((k) => stripVTControlCharacters(k)).join(' ') + pkg.keywords = data.keywords.map(strip) } else if (typeof data.keywords === 'string') { - pkg.keywords = stripVTControlCharacters(data.keywords.replace(/[,\s]+/, ' ')) - } - if (data.date) { - pkg.date = data.date.toISOString().split('T')[0] // remove time + pkg.keywords = strip(data.keywords.replace(/[,\s]+/, ' ')).split(' ') } - const columns = ['name', 'description', 'author', 'date', 'version', 'keywords'] - if (this.#opts.parseable) { - return columns.map((col) => pkg[col] && ('' + pkg[col]).replace(/\t/g, ' ')).join('\t') + let output + if (this.#parseable) { + output = [pkg.name, pkg.description, pkg.author, pkg.date, pkg.version, pkg.keywords] + .filter(Boolean) + .map(col => ('' + col).replace(/\t/g, ' ')).join('\t') + return super.write(output) } - // 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, - showHeaders: ++this.#line <= 1, - columnSplitter: ' | ', - truncate: !this.#opts.long, - config: { - name: { minWidth: 25, maxWidth: 25, truncate: false, truncateMarker: '' }, - description: { minWidth: 20, maxWidth: 20 }, - author: { minWidth: 15, maxWidth: 15 }, - date: { maxWidth: 11 }, - version: { minWidth: 8, maxWidth: 8 }, - keywords: { maxWidth: Infinity }, - }, + const keywords = pkg.keywords.map(k => { + if (this.#args.includes(k)) { + return this.#chalk.cyan(k) + } else { + return k + } + }).join(' ') + + let description = [] + for (const arg of this.#args) { + const finder = pkg.description.toLowerCase().split(arg.toLowerCase()) + let p = 0 + for (const f of finder) { + description.push(pkg.description.slice(p, p + f.length)) + const word = pkg.description.slice(p + f.length, p + f.length + arg.length) + description.push(this.#chalk.cyan(word)) + p += f.length + arg.length } - ).split('\n').map(line => line.slice(0, maxWidth)).join('\n') - - if (!this.#opts.color) { - return output } - - const colors = ['31m', '33m', '32m', '36m', '34m', '35m'] - - this.#opts.args.forEach((arg, i) => { - const markStart = String.fromCharCode(i % colors.length + 1) - const markEnd = String.fromCharCode(0) - - if (arg.charAt(0) === '/') { - output = output.replace( - new RegExp(arg.slice(1, -1), 'gi'), - bit => `${markStart}${bit}${markEnd}` - ) - } else { - // just a normal string, do the split/map thing + description = description.filter(Boolean) + let name = pkg.name + if (this.#args.includes(pkg.name)) { + name = this.#chalk.cyan(pkg.name) + } else { + name = [] + for (const arg of this.#args) { + const finder = pkg.name.toLowerCase().split(arg.toLowerCase()) let p = 0 - - output = output.toLowerCase().split(arg.toLowerCase()).map(piece => { - piece = output.slice(p, p + piece.length) - p += piece.length - const mark = `${markStart}${output.slice(p, p + arg.length)}${markEnd}` - p += arg.length - return `${piece}${mark}` - }).join('') + for (const f of finder) { + name.push(pkg.name.slice(p, p + f.length)) + const word = pkg.name.slice(p + f.length, p + f.length + arg.length) + name.push(this.#chalk.cyan(word)) + p += f.length + arg.length + } } - }) + name = this.#chalk.blue(name.join('')) + } - for (let i = 1; i <= colors.length; i++) { - output = output.split(String.fromCharCode(i)).join(`\u001B[${colors[i - 1]}`) + if (description.length) { + output = `${name}\n${description.join('')}\n` + } else { + output = `${name}\n` + } + if (pkg.publisher) { + output += `Version ${this.#chalk.blue(pkg.version)} published ${this.#chalk.blue(pkg.date)} by ${this.#chalk.blue(pkg.publisher)}\n` + } else { + output += `Version ${this.#chalk.blue(pkg.version)} published ${this.#chalk.blue(pkg.date)} by ${this.#chalk.yellow('???')}\n` + } + output += `Maintainers: ${pkg.authors}\n` + if (keywords) { + output += `Keywords: ${keywords}\n` } - return output.split('\u0000').join('\u001B[0m').trim() + output += `${this.#chalk.blue(`https://npm.im/${pkg.name}`)}\n` + return super.write(output) } } diff --git a/deps/npm/lib/utils/format.js b/deps/npm/lib/utils/format.js new file mode 100644 index 00000000000000..abfbf9e3317043 --- /dev/null +++ b/deps/npm/lib/utils/format.js @@ -0,0 +1,50 @@ +const { formatWithOptions: baseFormatWithOptions } = require('util') + +// These are most assuredly not a mistake +// https://eslint.org/docs/latest/rules/no-control-regex +// \x00 through \x1f, \x7f through \x9f, not including \x09 \x0a \x0b \x0d +/* eslint-disable-next-line no-control-regex */ +const HAS_C01 = /[\x00-\x08\x0c\x0e-\x1f\x7f-\x9f]/ + +// Allows everything up to '[38;5;255m' in 8 bit notation +const ALLOWED_SGR = /^\[[0-9;]{0,8}m/ + +// '[38;5;255m'.length +const SGR_MAX_LEN = 10 + +// Strips all ANSI C0 and C1 control characters (except for SGR up to 8 bit) +function STRIP_C01 (str) { + if (!HAS_C01.test(str)) { + return str + } + let result = '' + for (let i = 0; i < str.length; i++) { + const char = str[i] + const code = char.charCodeAt(0) + if (!HAS_C01.test(char)) { + // Most characters are in this set so continue early if we can + result = `${result}${char}` + } else if (code === 27 && ALLOWED_SGR.test(str.slice(i + 1, i + SGR_MAX_LEN + 1))) { + // \x1b with allowed SGR + result = `${result}\x1b` + } else if (code <= 31) { + // escape all other C0 control characters besides \x7f + result = `${result}^${String.fromCharCode(code + 64)}` + } else { + // hasC01 ensures this is now a C1 control character or \x7f + result = `${result}^${String.fromCharCode(code - 64)}` + } + } + return result +} + +const formatWithOptions = ({ prefix: prefixes = [], eol = '\n', ...options }, ...args) => { + const prefix = prefixes.filter(p => p != null).join(' ') + const formatted = STRIP_C01(baseFormatWithOptions(options, ...args)) + // Splitting could be changed to only `\n` once we are sure we only emit unix newlines. + // The eol param to this function will put the correct newlines in place for the returned string. + const lines = formatted.split(/\r?\n/) + return lines.reduce((acc, l) => `${acc}${prefix}${prefix && l ? ' ' : ''}${l}${eol}`, '') +} + +module.exports = { formatWithOptions } diff --git a/deps/npm/lib/workspaces/get-workspaces.js b/deps/npm/lib/utils/get-workspaces.js similarity index 100% rename from deps/npm/lib/workspaces/get-workspaces.js rename to deps/npm/lib/utils/get-workspaces.js diff --git a/deps/npm/lib/utils/completion/installed-deep.js b/deps/npm/lib/utils/installed-deep.js similarity index 100% rename from deps/npm/lib/utils/completion/installed-deep.js rename to deps/npm/lib/utils/installed-deep.js diff --git a/deps/npm/lib/utils/completion/installed-shallow.js b/deps/npm/lib/utils/installed-shallow.js similarity index 100% rename from deps/npm/lib/utils/completion/installed-shallow.js rename to deps/npm/lib/utils/installed-shallow.js diff --git a/deps/npm/lib/utils/is-windows.js b/deps/npm/lib/utils/is-windows.js index 57f6599b6ae192..63c5671d8400ee 100644 --- a/deps/npm/lib/utils/is-windows.js +++ b/deps/npm/lib/utils/is-windows.js @@ -1,6 +1,4 @@ -const isWindows = process.platform === 'win32' -const isWindowsShell = isWindows && +const isWindowsShell = (process.platform === 'win32') && !/^MINGW(32|64)$/.test(process.env.MSYSTEM) && process.env.TERM !== 'cygwin' -exports.isWindows = isWindows exports.isWindowsShell = isWindowsShell diff --git a/deps/npm/lib/utils/log-file.js b/deps/npm/lib/utils/log-file.js index 1a46b7da0d6604..09e3873f2dce6c 100644 --- a/deps/npm/lib/utils/log-file.js +++ b/deps/npm/lib/utils/log-file.js @@ -1,18 +1,16 @@ const os = require('os') const { join, dirname, basename } = require('path') -const { format } = require('util') -const { Minipass } = require('minipass') const fsMiniPass = require('fs-minipass') const fs = require('fs/promises') -const log = require('./log-shim') -const Display = require('./display') +const { log } = require('proc-log') +const { formatWithOptions } = require('./format') const padZero = (n, length) => n.toString().padStart(length.toString().length, '0') class LogFiles { - // Default to a plain minipass stream so we can buffer + // Default to an array so we can buffer // initial writes before we know the cache location - #logStream = null + #logStream = [] // We cap log files at a certain number of log events per file. // Note that each log event can write more than one line to the @@ -30,6 +28,7 @@ class LogFiles { #path = null #logsMax = null #files = [] + #timing = false constructor ({ maxLogsPerFile = 50_000, @@ -40,23 +39,7 @@ class LogFiles { this.on() } - static format (count, level, title, ...args) { - let prefix = `${count} ${level}` - if (title) { - prefix += ` ${title}` - } - - return format(...args) - .split(/\r?\n/) - .map(Display.clean) - .reduce((lines, line) => - lines += prefix + (line ? ' ' : '') + line + os.EOL, - '' - ) - } - on () { - this.#logStream = new Minipass() process.on('log', this.#logHandler) } @@ -65,11 +48,12 @@ class LogFiles { this.#endStream() } - load ({ path, logsMax = Infinity } = {}) { + load ({ path, logsMax = Infinity, timing } = {}) { // dir is user configurable and is required to exist so // this can error if the dir is missing or not configured correctly this.#path = path this.#logsMax = logsMax + this.#timing = timing // Log stream has already ended if (!this.#logStream) { @@ -78,36 +62,40 @@ class LogFiles { log.verbose('logfile', `logs-max:${logsMax} dir:${this.#path}`) - // Pipe our initial stream to our new file stream and + // Write the contents of our array buffer to our new file stream and // set that as the new log logstream for future writes // if logs max is 0 then the user does not want a log file if (this.#logsMax > 0) { const initialFile = this.#openLogFile() if (initialFile) { - this.#logStream = this.#logStream.pipe(initialFile) + for (const item of this.#logStream) { + const formatted = this.#formatLogItem(...item) + if (formatted !== null) { + initialFile.write(formatted) + } + } + this.#logStream = initialFile } } + log.verbose('logfile', this.files[0] || 'no logfile created') + // Kickoff cleaning process, even if we aren't writing a logfile. // This is async but it will always ignore the current logfile // Return the result so it can be awaited in tests return this.#cleanLogs() } - log (...args) { - this.#logHandler(...args) - } - get files () { return this.#files } get #isBuffered () { - return this.#logStream instanceof Minipass + return Array.isArray(this.#logStream) } #endStream (output) { - if (this.#logStream) { + if (this.#logStream && !this.#isBuffered) { this.#logStream.end(output) this.#logStream = null } @@ -125,12 +113,15 @@ class LogFiles { return } - const logOutput = this.#formatLogItem(level, ...args) - if (this.#isBuffered) { // Cant do anything but buffer the output if we dont // have a file stream yet - this.#logStream.write(logOutput) + this.#logStream.push([level, ...args]) + return + } + + const logOutput = this.#formatLogItem(level, ...args) + if (logOutput === null) { return } @@ -150,9 +141,15 @@ class LogFiles { } } - #formatLogItem (...args) { + #formatLogItem (level, title, ...args) { + // Only right timing logs to logfile if explicitly requests + if (level === log.KEYS.timing && !this.#timing) { + return null + } + this.#fileLogCount += 1 - return LogFiles.format(this.#totalLogCount++, ...args) + const prefix = [this.#totalLogCount++, level, title || null] + return formatWithOptions({ prefix, eol: os.EOL, colors: false }, ...args) } #getLogFilePath (count = '') { @@ -249,7 +246,7 @@ class LogFiles { } catch (e) { // Disable cleanup failure warnings when log writing is disabled if (this.#logsMax > 0) { - log.warn('logfile', 'error cleaning log files', e) + log.verbose('logfile', 'error cleaning log files', e) } } finally { log.silly('logfile', 'done cleaning log files') diff --git a/deps/npm/lib/utils/log-shim.js b/deps/npm/lib/utils/log-shim.js deleted file mode 100644 index 9d5a36d967413f..00000000000000 --- a/deps/npm/lib/utils/log-shim.js +++ /dev/null @@ -1,59 +0,0 @@ -const NPMLOG = require('npmlog') -const PROCLOG = require('proc-log') - -// Sets getter and optionally a setter -// otherwise setting should throw -const accessors = (obj, set) => (k) => ({ - get: () => obj[k], - set: set ? (v) => (obj[k] = v) : () => { - throw new Error(`Cant set ${k}`) - }, -}) - -// Set the value to a bound function on the object -const value = (obj) => (k) => ({ - value: (...args) => obj[k].apply(obj, args), -}) - -const properties = { - // npmlog getters/setters - level: accessors(NPMLOG, true), - heading: accessors(NPMLOG, true), - levels: accessors(NPMLOG), - gauge: accessors(NPMLOG), - stream: accessors(NPMLOG), - tracker: accessors(NPMLOG), - progressEnabled: accessors(NPMLOG), - // npmlog methods - useColor: value(NPMLOG), - enableColor: value(NPMLOG), - disableColor: value(NPMLOG), - enableUnicode: value(NPMLOG), - disableUnicode: value(NPMLOG), - enableProgress: value(NPMLOG), - disableProgress: value(NPMLOG), - clearProgress: value(NPMLOG), - showProgress: value(NPMLOG), - newItem: value(NPMLOG), - newGroup: value(NPMLOG), - // proclog methods - notice: value(PROCLOG), - error: value(PROCLOG), - warn: value(PROCLOG), - info: value(PROCLOG), - verbose: value(PROCLOG), - http: value(PROCLOG), - silly: value(PROCLOG), - pause: value(PROCLOG), - resume: value(PROCLOG), -} - -const descriptors = Object.entries(properties).reduce((acc, [k, v]) => { - acc[k] = { enumerable: true, ...v(k) } - return acc -}, {}) - -// Create an object with the allowed properties rom npm log and all -// the logging methods from proc log -// XXX: this should go away and requires of this should be replaced with proc-log + new display -module.exports = Object.freeze(Object.defineProperties({}, descriptors)) diff --git a/deps/npm/lib/utils/open-url-prompt.js b/deps/npm/lib/utils/open-url-prompt.js index 71a68c253c0505..6f4d453a959d59 100644 --- a/deps/npm/lib/utils/open-url-prompt.js +++ b/deps/npm/lib/utils/open-url-prompt.js @@ -1,4 +1,5 @@ const readline = require('readline') +const { input, output } = require('proc-log') const open = require('./open-url.js') function print (npm, title, url) { @@ -6,7 +7,7 @@ function print (npm, title, url) { const message = json ? JSON.stringify({ title, url }) : `${title}:\n${url}` - npm.output(message) + output.standard(message) } // Prompt to open URL in browser if possible @@ -33,7 +34,7 @@ const promptOpen = async (npm, url, title, prompt, emitter) => { output: process.stdout, }) - const tryOpen = await new Promise(resolve => { + const tryOpen = await input.read(() => new Promise(resolve => { rl.on('SIGINT', () => { rl.close() resolve('SIGINT') @@ -46,14 +47,10 @@ const promptOpen = async (npm, url, title, prompt, emitter) => { if (emitter && emitter.addListener) { emitter.addListener('abort', () => { rl.close() - - // clear the prompt line - npm.output('') - resolve(false) }) } - }) + })) if (tryOpen === 'SIGINT') { throw new Error('canceled') diff --git a/deps/npm/lib/utils/open-url.js b/deps/npm/lib/utils/open-url.js index 77bb1d03d8e165..46b7abc731fa1d 100644 --- a/deps/npm/lib/utils/open-url.js +++ b/deps/npm/lib/utils/open-url.js @@ -1,4 +1,5 @@ const promiseSpawn = require('@npmcli/promise-spawn') +const { output } = require('proc-log') const { URL } = require('url') @@ -16,7 +17,7 @@ const open = async (npm, url, errMsg, isFile) => { }, null, 2) : `${errMsg}:\n ${url}\n` - npm.output(alternateMsg) + output.standard(alternateMsg) } if (browser === false) { diff --git a/deps/npm/lib/utils/otplease.js b/deps/npm/lib/utils/otplease.js index b4aa1674692551..b8dd0b66ed7664 100644 --- a/deps/npm/lib/utils/otplease.js +++ b/deps/npm/lib/utils/otplease.js @@ -1,4 +1,3 @@ -const log = require('./log-shim') async function otplease (npm, opts, fn) { try { return await fn(opts) @@ -8,7 +7,6 @@ async function otplease (npm, opts, fn) { } if (isWebOTP(err)) { - log.disableProgress() const webAuth = require('./web-auth') const openUrlPrompt = require('./open-url-prompt') diff --git a/deps/npm/lib/utils/pulse-till-done.js b/deps/npm/lib/utils/pulse-till-done.js deleted file mode 100644 index 22294141474839..00000000000000 --- a/deps/npm/lib/utils/pulse-till-done.js +++ /dev/null @@ -1,26 +0,0 @@ -const log = require('./log-shim.js') - -let pulseTimer = null -const withPromise = async (promise) => { - pulseStart() - try { - return await promise - } finally { - pulseStop() - } -} - -const pulseStart = () => { - pulseTimer = pulseTimer || setInterval(() => { - log.gauge.pulse('') - }, 150) -} - -const pulseStop = () => { - clearInterval(pulseTimer) - pulseTimer = null -} - -module.exports = { - withPromise, -} diff --git a/deps/npm/lib/utils/read-user-info.js b/deps/npm/lib/utils/read-user-info.js index fa1cea158e8974..4e8def4bdf1def 100644 --- a/deps/npm/lib/utils/read-user-info.js +++ b/deps/npm/lib/utils/read-user-info.js @@ -1,6 +1,6 @@ -const { read } = require('read') +const { read: _read } = require('read') const userValidate = require('npm-user-validate') -const log = require('./log-shim.js') +const { log, input } = require('proc-log') exports.otp = readOTP exports.password = readPassword @@ -16,17 +16,14 @@ const passwordPrompt = 'npm password: ' const usernamePrompt = 'npm username: ' const emailPrompt = 'email (this IS public): ' -function readWithProgress (opts) { - log.clearProgress() - return read(opts).finally(() => log.showProgress()) -} +const read = (...args) => input.read(() => _read(...args)) function readOTP (msg = otpPrompt, otp, isRetry) { if (isRetry && otp && /^[\d ]+$|^[A-Fa-f0-9]{64,64}$/.test(otp)) { return otp.replace(/\s+/g, '') } - return readWithProgress({ prompt: msg, default: otp || '' }) + return read({ prompt: msg, default: otp || '' }) .then((rOtp) => readOTP(msg, rOtp, true)) } @@ -35,7 +32,7 @@ function readPassword (msg = passwordPrompt, password, isRetry) { return password } - return readWithProgress({ prompt: msg, silent: true, default: password || '' }) + return read({ prompt: msg, silent: true, default: password || '' }) .then((rPassword) => readPassword(msg, rPassword, true)) } @@ -49,7 +46,7 @@ function readUsername (msg = usernamePrompt, username, isRetry) { } } - return readWithProgress({ prompt: msg, default: username || '' }) + return read({ prompt: msg, default: username || '' }) .then((rUsername) => readUsername(msg, rUsername, true)) } @@ -63,6 +60,6 @@ function readEmail (msg = emailPrompt, email, isRetry) { } } - return readWithProgress({ prompt: msg, default: email || '' }) + return read({ prompt: msg, default: email || '' }) .then((username) => readEmail(msg, username, true)) } diff --git a/deps/npm/lib/utils/reify-finish.js b/deps/npm/lib/utils/reify-finish.js index 9b43abcb7610a1..0b34a375768606 100644 --- a/deps/npm/lib/utils/reify-finish.js +++ b/deps/npm/lib/utils/reify-finish.js @@ -1,6 +1,6 @@ const reifyOutput = require('./reify-output.js') const ini = require('ini') -const { writeFile } = require('fs').promises +const { writeFile } = require('fs/promises') const { resolve } = require('path') const reifyFinish = async (npm, arb) => { diff --git a/deps/npm/lib/utils/reify-output.js b/deps/npm/lib/utils/reify-output.js index 44c913812a8efe..a858a546c4010c 100644 --- a/deps/npm/lib/utils/reify-output.js +++ b/deps/npm/lib/utils/reify-output.js @@ -9,13 +9,12 @@ // found 37 vulnerabilities (5 low, 7 moderate, 25 high) // run `npm audit fix` to fix them, or `npm audit` for details -const log = require('./log-shim.js') +const { log, output } = require('proc-log') const { depth } = require('treeverse') const ms = require('ms') const npmAuditReport = require('npm-audit-report') const { readTree: getFundingInfo } = require('libnpmfund') const auditError = require('./audit-error.js') -const Table = require('cli-table3') // TODO: output JSON if flatOptions.json is true const reifyOutput = (npm, arb) => { @@ -42,51 +41,31 @@ const reifyOutput = (npm, arb) => { } if (diff) { - let diffTable - if (npm.config.get('dry-run') || npm.config.get('long')) { - diffTable = new Table({ - chars: { - top: '', - 'top-mid': '', - 'top-left': '', - 'top-right': '', - bottom: '', - 'bottom-mid': '', - 'bottom-left': '', - 'bottom-right': '', - left: '', - 'left-mid': '', - mid: '', - 'mid-mid': '', - right: '', - 'right-mid': '', - middle: ' ', - }, - style: { - 'padding-left': 0, - 'padding-right': 0, - border: 0, - }, - }) - } + const showDiff = npm.config.get('dry-run') || npm.config.get('long') + const chalk = npm.chalk depth({ tree: diff, visit: d => { switch (d.action) { case 'REMOVE': - diffTable?.push(['remove', d.actual.name, d.actual.package.version]) + if (showDiff) { + /* eslint-disable-next-line max-len */ + output.standard(`${chalk.blue('remove')} ${d.actual.name} ${d.actual.package.version}`) + } summary.removed++ break case 'ADD': - diffTable?.push(['add', d.ideal.name, d.ideal.package.version]) + if (showDiff) { + output.standard(`${chalk.green('add')} ${d.ideal.name} ${d.ideal.package.version}`) + } actualTree.inventory.has(d.ideal) && summary.added++ break case 'CHANGE': - diffTable?.push(['change', - d.actual.name, - d.actual.package.version + ' -> ' + d.ideal.package.version, - ]) + if (showDiff) { + /* eslint-disable-next-line max-len */ + output.standard(`${chalk.cyan('change')} ${d.actual.name} ${d.actual.package.version} => ${d.ideal.package.version}`) + } summary.changed++ break default: @@ -97,10 +76,6 @@ const reifyOutput = (npm, arb) => { }, getChildren: d => d.children, }) - - if (diffTable) { - npm.output('\n' + diffTable.toString()) - } } if (npm.flatOptions.fund) { @@ -115,7 +90,7 @@ const reifyOutput = (npm, arb) => { summary.audit = npm.command === 'audit' ? auditReport : auditReport.toJSON().metadata } - npm.output(JSON.stringify(summary, null, 2)) + output.standard(JSON.stringify(summary, null, 2)) } else { packagesChangedMessage(npm, summary) packagesFundingMessage(npm, summary) @@ -134,7 +109,7 @@ const printAuditReport = (npm, report) => { if (!res || !res.report) { return } - npm.output(`\n${res.report}`) + output.standard(`\n${res.report}`) } const getAuditReport = (npm, report) => { @@ -206,7 +181,7 @@ const packagesChangedMessage = (npm, { added, removed, changed, audited }) => { } msg.push(` in ${ms(Date.now() - npm.started)}`) - npm.output(msg.join('')) + output.standard(msg.join('')) } const packagesFundingMessage = (npm, { funding }) => { @@ -214,11 +189,11 @@ const packagesFundingMessage = (npm, { funding }) => { return } - npm.output('') + output.standard('') const pkg = funding === 1 ? 'package' : 'packages' const is = funding === 1 ? 'is' : 'are' - npm.output(`${funding} ${pkg} ${is} looking for funding`) - npm.output(' run `npm fund` for details') + output.standard(`${funding} ${pkg} ${is} looking for funding`) + output.standard(' run `npm fund` for details') } module.exports = reifyOutput diff --git a/deps/npm/lib/utils/tar.js b/deps/npm/lib/utils/tar.js index c25fe71614a60b..9085d9dd350165 100644 --- a/deps/npm/lib/utils/tar.js +++ b/deps/npm/lib/utils/tar.js @@ -1,8 +1,7 @@ const tar = require('tar') const ssri = require('ssri') -const log = require('./log-shim') +const { log } = require('proc-log') const formatBytes = require('./format-bytes.js') -const columnify = require('columnify') const localeCompare = require('@isaacs/string-locale-compare')('en', { sensitivity: 'case', numeric: true, @@ -12,60 +11,36 @@ const logTar = (tarball, opts = {}) => { const { unicode = false } = opts log.notice('') log.notice('', `${unicode ? '📦 ' : 'package:'} ${tarball.name}@${tarball.version}`) - log.notice('=== Tarball Contents ===') + log.notice('Tarball Contents') if (tarball.files.length) { log.notice( '', - columnify( - tarball.files - .map(f => { - const bytes = formatBytes(f.size, false) - return /^node_modules\//.test(f.path) ? null : { path: f.path, size: `${bytes}` } - }) - .filter(f => f), - { - include: ['size', 'path'], - showHeaders: false, - } - ) + tarball.files.map(f => + /^node_modules\//.test(f.path) ? null : `${formatBytes(f.size, false)} ${f.path}` + ).filter(f => f).join('\n') ) } if (tarball.bundled.length) { - log.notice('=== Bundled Dependencies ===') + log.notice('Bundled Dependencies') tarball.bundled.forEach(name => log.notice('', name)) } - log.notice('=== Tarball Details ===') - log.notice( - '', - columnify( - [ - { name: 'name:', value: tarball.name }, - { name: 'version:', value: tarball.version }, - tarball.filename && { name: 'filename:', value: tarball.filename }, - { name: 'package size:', value: formatBytes(tarball.size) }, - { name: 'unpacked size:', value: formatBytes(tarball.unpackedSize) }, - { name: 'shasum:', value: tarball.shasum }, - { - name: 'integrity:', - value: - tarball.integrity.toString().slice(0, 20) + - '[...]' + - tarball.integrity.toString().slice(80), - }, - tarball.bundled.length && { name: 'bundled deps:', value: tarball.bundled.length }, - tarball.bundled.length && { - name: 'bundled files:', - value: tarball.entryCount - tarball.files.length, - }, - tarball.bundled.length && { name: 'own files:', value: tarball.files.length }, - { name: 'total files:', value: tarball.entryCount }, - ].filter(x => x), - { - include: ['name', 'value'], - showHeaders: false, - } - ) - ) + log.notice('Tarball Details') + log.notice('', `name: ${tarball.name}`) + log.notice('', `version: ${tarball.version}`) + if (tarball.filename) { + log.notice('', `filename: ${tarball.filename}`) + } + log.notice('', `package size: ${formatBytes(tarball.size)}`) + log.notice('', `unpacked size: ${formatBytes(tarball.unpackedSize)}`) + log.notice('', `shasum: ${tarball.shasum}`) + /* eslint-disable-next-line max-len */ + log.notice('', `integrity: ${tarball.integrity.toString().slice(0, 20)}[...]${tarball.integrity.toString().slice(80)}`) + if (tarball.bundled.length) { + log.notice('', `bundled deps: ${tarball.bundled.length}`) + log.notice('', `bundled files: ${tarball.entryCount - tarball.files.length}`) + log.notice('', `own files: ${tarball.files.length}`) + } + log.notice('', `total files: ${tarball.entryCount}`) log.notice('', '') } diff --git a/deps/npm/lib/utils/timers.js b/deps/npm/lib/utils/timers.js index c215fe926afb59..16a255961fee3b 100644 --- a/deps/npm/lib/utils/timers.js +++ b/deps/npm/lib/utils/timers.js @@ -1,114 +1,87 @@ -const EE = require('events') -const fs = require('fs') -const log = require('./log-shim') +const EE = require('node:events') +const fs = require('node:fs') +const { log, time } = require('proc-log') + +const INITIAL_TIMER = 'npm' -// This is an event emiiter but on/off -// only listen on a single internal event that gets -// emitted whenever a timer ends class Timers extends EE { - file = null + #file + #timing #unfinished = new Map() #finished = {} - #onTimeEnd = Symbol('onTimeEnd') - #initialListener = null - #initialTimer = null - constructor ({ listener = null, start = 'npm' } = {}) { + constructor () { super() - this.#initialListener = listener - this.#initialTimer = start - this.#init() - } - - get unfinished () { - return this.#unfinished - } - - get finished () { - return this.#finished - } - - #init () { this.on() - if (this.#initialListener) { - this.on(this.#initialListener) - } - process.emit('time', this.#initialTimer) - this.started = this.#unfinished.get(this.#initialTimer) + time.start(INITIAL_TIMER) + this.started = this.#unfinished.get(INITIAL_TIMER) } - on (listener) { - if (listener) { - super.on(this.#onTimeEnd, listener) - } else { - process.on('time', this.#timeListener) - process.on('timeEnd', this.#timeEndListener) - } + on () { + process.on('time', this.#timeHandler) } - off (listener) { - if (listener) { - super.off(this.#onTimeEnd, listener) - } else { - this.removeAllListeners(this.#onTimeEnd) - process.off('time', this.#timeListener) - process.off('timeEnd', this.#timeEndListener) - } + off () { + process.off('time', this.#timeHandler) } - time (name, fn) { - process.emit('time', name) - const end = () => process.emit('timeEnd', name) - if (typeof fn === 'function') { - const res = fn() - return res && res.finally ? res.finally(end) : (end(), res) - } - return end + load ({ path, timing } = {}) { + this.#timing = timing + this.#file = `${path}timing.json` } - load ({ path } = {}) { - if (path) { - this.file = `${path}timing.json` + finish (metadata) { + time.end(INITIAL_TIMER) + + for (const [name, timer] of this.#unfinished) { + log.silly('unfinished npm timer', name, timer) } - } - writeFile (metadata) { - if (!this.file) { + if (!this.#timing) { + // Not in timing mode, nothing else to do here return } try { - const globalStart = this.started - const globalEnd = this.#finished.npm || Date.now() - const content = { - metadata, - timers: this.#finished, - // add any unfinished timers with their relative start/end - unfinishedTimers: [...this.#unfinished.entries()].reduce((acc, [name, start]) => { - acc[name] = [start - globalStart, globalEnd - globalStart] - return acc - }, {}), - } - fs.writeFileSync(this.file, JSON.stringify(content) + '\n') + this.#writeFile(metadata) + log.info('timing', `Timing info written to: ${this.#file}`) } catch (e) { - this.file = null log.warn('timing', `could not write timing file: ${e}`) } } - #timeListener = (name) => { - this.#unfinished.set(name, Date.now()) + #writeFile (metadata) { + const globalStart = this.started + const globalEnd = this.#finished[INITIAL_TIMER] + const content = { + metadata, + timers: this.#finished, + // add any unfinished timers with their relative start/end + unfinishedTimers: [...this.#unfinished.entries()].reduce((acc, [name, start]) => { + acc[name] = [start - globalStart, globalEnd - globalStart] + return acc + }, {}), + } + fs.writeFileSync(this.#file, JSON.stringify(content) + '\n') } - #timeEndListener = (name) => { - if (this.#unfinished.has(name)) { - const ms = Date.now() - this.#unfinished.get(name) - this.#finished[name] = ms - this.#unfinished.delete(name) - this.emit(this.#onTimeEnd, name, ms) - } else { - log.silly('timing', "Tried to end timer that doesn't exist:", name) + #timeHandler = (level, name) => { + const now = Date.now() + switch (level) { + case time.KEYS.start: + this.#unfinished.set(name, now) + break + case time.KEYS.end: { + if (this.#unfinished.has(name)) { + const ms = now - this.#unfinished.get(name) + this.#finished[name] = ms + this.#unfinished.delete(name) + log.timing(name, `Completed in ${ms}ms`) + } else { + log.silly('timing', `Tried to end timer that doesn't exist: ${name}`) + } + } } } } diff --git a/deps/npm/lib/workspaces/update-workspaces.js b/deps/npm/lib/utils/update-workspaces.js similarity index 100% rename from deps/npm/lib/workspaces/update-workspaces.js rename to deps/npm/lib/utils/update-workspaces.js diff --git a/deps/npm/lib/utils/verify-signatures.js b/deps/npm/lib/utils/verify-signatures.js new file mode 100644 index 00000000000000..f2973316c9b767 --- /dev/null +++ b/deps/npm/lib/utils/verify-signatures.js @@ -0,0 +1,389 @@ +const fetch = require('npm-registry-fetch') +const localeCompare = require('@isaacs/string-locale-compare')('en') +const npa = require('npm-package-arg') +const pacote = require('pacote') +const pMap = require('p-map') +const tufClient = require('@sigstore/tuf') +const { log, output } = require('proc-log') + +const sortAlphabetically = (a, b) => localeCompare(a.name, b.name) + +class VerifySignatures { + constructor (tree, filterSet, npm, opts) { + this.tree = tree + this.filterSet = filterSet + this.npm = npm + this.opts = opts + this.keys = new Map() + this.invalid = [] + this.missing = [] + this.checkedPackages = new Set() + this.auditedWithKeysCount = 0 + this.verifiedSignatureCount = 0 + this.verifiedAttestationCount = 0 + this.exitCode = 0 + } + + async run () { + const start = process.hrtime.bigint() + + // Find all deps in tree + const { edges, registries } = this.getEdgesOut(this.tree.inventory.values(), this.filterSet) + if (edges.size === 0) { + throw new Error('found no installed dependencies to audit') + } + + const tuf = await tufClient.initTUF({ + cachePath: this.opts.tufCache, + retry: this.opts.retry, + timeout: this.opts.timeout, + }) + await Promise.all([...registries].map(registry => this.setKeys({ registry, tuf }))) + + log.verbose('verifying registry signatures') + await pMap(edges, (e) => this.getVerifiedInfo(e), { concurrency: 20, stopOnError: true }) + + // Didn't find any dependencies that could be verified, e.g. only local + // deps, missing version, not on a registry etc. + if (!this.auditedWithKeysCount) { + throw new Error('found no dependencies to audit that were installed from ' + + 'a supported registry') + } + + const invalid = this.invalid.sort(sortAlphabetically) + const missing = this.missing.sort(sortAlphabetically) + + const hasNoInvalidOrMissing = invalid.length === 0 && missing.length === 0 + + if (!hasNoInvalidOrMissing) { + process.exitCode = 1 + } + + if (this.npm.config.get('json')) { + output.standard(JSON.stringify({ + invalid, + missing, + }, null, 2)) + return + } + const end = process.hrtime.bigint() + const elapsed = end - start + + const auditedPlural = this.auditedWithKeysCount > 1 ? 's' : '' + const timing = `audited ${this.auditedWithKeysCount} package${auditedPlural} in ` + + `${Math.floor(Number(elapsed) / 1e9)}s` + output.standard(timing) + output.standard('') + + const verifiedBold = this.npm.chalk.bold('verified') + if (this.verifiedSignatureCount) { + if (this.verifiedSignatureCount === 1) { + /* eslint-disable-next-line max-len */ + output.standard(`${this.verifiedSignatureCount} package has a ${verifiedBold} registry signature`) + } else { + /* eslint-disable-next-line max-len */ + output.standard(`${this.verifiedSignatureCount} packages have ${verifiedBold} registry signatures`) + } + output.standard('') + } + + if (this.verifiedAttestationCount) { + if (this.verifiedAttestationCount === 1) { + /* eslint-disable-next-line max-len */ + output.standard(`${this.verifiedAttestationCount} package has a ${verifiedBold} attestation`) + } else { + /* eslint-disable-next-line max-len */ + output.standard(`${this.verifiedAttestationCount} packages have ${verifiedBold} attestations`) + } + output.standard('') + } + + if (missing.length) { + const missingClr = this.npm.chalk.redBright('missing') + if (missing.length === 1) { + /* eslint-disable-next-line max-len */ + output.standard(`1 package has a ${missingClr} registry signature but the registry is providing signing keys:`) + } else { + /* eslint-disable-next-line max-len */ + output.standard(`${missing.length} packages have ${missingClr} registry signatures but the registry is providing signing keys:`) + } + output.standard('') + missing.map(m => + output.standard(`${this.npm.chalk.red(`${m.name}@${m.version}`)} (${m.registry})`) + ) + } + + if (invalid.length) { + if (missing.length) { + output.standard('') + } + const invalidClr = this.npm.chalk.redBright('invalid') + // We can have either invalid signatures or invalid provenance + const invalidSignatures = this.invalid.filter(i => i.code === 'EINTEGRITYSIGNATURE') + if (invalidSignatures.length) { + if (invalidSignatures.length === 1) { + output.standard(`1 package has an ${invalidClr} registry signature:`) + } else { + /* eslint-disable-next-line max-len */ + output.standard(`${invalidSignatures.length} packages have ${invalidClr} registry signatures:`) + } + output.standard('') + invalidSignatures.map(i => + output.standard(`${this.npm.chalk.red(`${i.name}@${i.version}`)} (${i.registry})`) + ) + output.standard('') + } + + const invalidAttestations = this.invalid.filter(i => i.code === 'EATTESTATIONVERIFY') + if (invalidAttestations.length) { + if (invalidAttestations.length === 1) { + output.standard(`1 package has an ${invalidClr} attestation:`) + } else { + /* eslint-disable-next-line max-len */ + output.standard(`${invalidAttestations.length} packages have ${invalidClr} attestations:`) + } + output.standard('') + invalidAttestations.map(i => + output.standard(`${this.npm.chalk.red(`${i.name}@${i.version}`)} (${i.registry})`) + ) + output.standard('') + } + + if (invalid.length === 1) { + /* eslint-disable-next-line max-len */ + output.standard(`Someone might have tampered with this package since it was published on the registry!`) + } else { + /* eslint-disable-next-line max-len */ + output.standard(`Someone might have tampered with these packages since they were published on the registry!`) + } + output.standard('') + } + } + + getEdgesOut (nodes, filterSet) { + const edges = new Set() + const registries = new Set() + for (const node of nodes) { + for (const edge of node.edgesOut.values()) { + const filteredOut = + edge.from + && filterSet + && filterSet.size > 0 + && !filterSet.has(edge.from.target) + + if (!filteredOut) { + const spec = this.getEdgeSpec(edge) + if (spec) { + // Prefetch and cache public keys from used registries + registries.add(this.getSpecRegistry(spec)) + } + edges.add(edge) + } + } + } + return { edges, registries } + } + + async setKeys ({ registry, tuf }) { + const { host, pathname } = new URL(registry) + // Strip any trailing slashes from pathname + const regKey = `${host}${pathname.replace(/\/$/, '')}/keys.json` + let keys = await tuf.getTarget(regKey) + .then((target) => JSON.parse(target)) + .then(({ keys: ks }) => ks.map((key) => ({ + ...key, + keyid: key.keyId, + pemkey: `-----BEGIN PUBLIC KEY-----\n${key.publicKey.rawBytes}\n-----END PUBLIC KEY-----`, + expires: key.publicKey.validFor.end || null, + }))).catch(err => { + if (err.code === 'TUF_FIND_TARGET_ERROR') { + return null + } else { + throw err + } + }) + + // If keys not found in Sigstore TUF repo, fallback to registry keys API + if (!keys) { + keys = await fetch.json('/-/npm/v1/keys', { + ...this.npm.flatOptions, + registry, + }).then(({ keys: ks }) => ks.map((key) => ({ + ...key, + pemkey: `-----BEGIN PUBLIC KEY-----\n${key.key}\n-----END PUBLIC KEY-----`, + }))).catch(err => { + if (err.code === 'E404' || err.code === 'E400') { + return null + } else { + throw err + } + }) + } + + if (keys) { + this.keys.set(registry, keys) + } + } + + getEdgeType (edge) { + return edge.optional ? 'optionalDependencies' + : edge.peer ? 'peerDependencies' + : edge.dev ? 'devDependencies' + : 'dependencies' + } + + getEdgeSpec (edge) { + let name = edge.name + try { + name = npa(edge.spec).subSpec.name + } catch { + // leave it as edge.name + } + try { + return npa(`${name}@${edge.spec}`) + } catch { + // Skip packages with invalid spec + } + } + + buildRegistryConfig (registry) { + const keys = this.keys.get(registry) || [] + const parsedRegistry = new URL(registry) + const regKey = `//${parsedRegistry.host}${parsedRegistry.pathname}` + return { + [`${regKey}:_keys`]: keys, + } + } + + getSpecRegistry (spec) { + return fetch.pickRegistry(spec, this.npm.flatOptions) + } + + getValidPackageInfo (edge) { + const type = this.getEdgeType(edge) + // Skip potentially optional packages that are not on disk, as these could + // be omitted during install + if (edge.error === 'MISSING' && type !== 'dependencies') { + return + } + + const spec = this.getEdgeSpec(edge) + // Skip invalid version requirements + if (!spec) { + return + } + const node = edge.to || edge + const { version } = node.package || {} + + if (node.isWorkspace || // Skip local workspaces packages + !version || // Skip packages that don't have a installed version, e.g. optonal dependencies + !spec.registry) { // Skip if not from registry, e.g. git package + return + } + + for (const omitType of this.npm.config.get('omit')) { + if (node[omitType]) { + return + } + } + + return { + name: spec.name, + version, + type, + location: node.location, + registry: this.getSpecRegistry(spec), + } + } + + async verifySignatures (name, version, registry) { + const { + _integrity: integrity, + _signatures, + _attestations, + _resolved: resolved, + } = await pacote.manifest(`${name}@${version}`, { + verifySignatures: true, + verifyAttestations: true, + ...this.buildRegistryConfig(registry), + ...this.npm.flatOptions, + }) + const signatures = _signatures || [] + const result = { + integrity, + signatures, + attestations: _attestations, + resolved, + } + return result + } + + async getVerifiedInfo (edge) { + const info = this.getValidPackageInfo(edge) + if (!info) { + return + } + const { name, version, location, registry, type } = info + if (this.checkedPackages.has(location)) { + // we already did or are doing this one + return + } + this.checkedPackages.add(location) + + // We only "audit" or verify the signature, or the presence of it, on + // packages whose registry returns signing keys + const keys = this.keys.get(registry) || [] + if (keys.length) { + this.auditedWithKeysCount += 1 + } + + try { + const { integrity, signatures, attestations, resolved } = await this.verifySignatures( + name, version, registry + ) + + // Currently we only care about missing signatures on registries that provide a public key + // We could make this configurable in the future with a strict/paranoid mode + if (signatures.length) { + this.verifiedSignatureCount += 1 + } else if (keys.length) { + this.missing.push({ + integrity, + location, + name, + registry, + resolved, + version, + }) + } + + // Track verified attestations separately to registry signatures, as all + // packages on registries with signing keys are expected to have registry + // signatures, but not all packages have provenance and publish attestations. + if (attestations) { + this.verifiedAttestationCount += 1 + } + } catch (e) { + if (e.code === 'EINTEGRITYSIGNATURE' || e.code === 'EATTESTATIONVERIFY') { + this.invalid.push({ + code: e.code, + message: e.message, + integrity: e.integrity, + keyid: e.keyid, + location, + name, + registry, + resolved: e.resolved, + signature: e.signature, + predicateType: e.predicateType, + type, + version, + }) + } else { + throw e + } + } + } +} + +module.exports = VerifySignatures diff --git a/deps/npm/man/man1/npm-access.1 b/deps/npm/man/man1/npm-access.1 index f11a6a5ba98230..df63b4a6a5d6c6 100644 --- a/deps/npm/man/man1/npm-access.1 +++ b/deps/npm/man/man1/npm-access.1 @@ -5,7 +5,7 @@ .P .RS 2 .nf -npm access list packages \[lB]|| \[lB]\[rB] +npm access list packages \[lB]||\[rB] \[lB]\[rB] npm access list collaborators \[lB] \[lB]\[rB]\[rB] npm access get status \[lB]\[rB] npm access set status=public|private \[lB]\[rB] diff --git a/deps/npm/man/man1/npm-doctor.1 b/deps/npm/man/man1/npm-doctor.1 index 1aa4af1e485b08..16ae2f7e41715b 100644 --- a/deps/npm/man/man1/npm-doctor.1 +++ b/deps/npm/man/man1/npm-doctor.1 @@ -5,7 +5,7 @@ .P .RS 2 .nf -npm doctor \[lB]ping\[rB] \[lB]registry\[rB] \[lB]versions\[rB] \[lB]environment\[rB] \[lB]permissions\[rB] \[lB]cache\[rB] +npm doctor \[lB]connection\[rB] \[lB]registry\[rB] \[lB]versions\[rB] \[lB]environment\[rB] \[lB]permissions\[rB] \[lB]cache\[rB] .fi .RE .P @@ -30,21 +30,21 @@ Without all of these working properly, npm may not work properly. Many issues ar Also, in addition to this, there are also very many issue reports due to using old versions of npm. Since npm is constantly improving, running \fBnpm@latest\fR is better than an old version. .P \fBnpm doctor\fR verifies the following items in your environment, and if there are any recommended changes, it will display them. By default npm runs all of these checks. You can limit what checks are ran by specifying them as extra arguments. -.SS "\fBnpm ping\fR" +.SS "\fBConnecting to the registry\fR" .P -By default, npm installs from the primary npm registry, \fBregistry.npmjs.org\fR. \fBnpm doctor\fR hits a special ping endpoint within the registry. This can also be checked with \fBnpm ping\fR. If this check fails, you may be using a proxy that needs to be configured, or may need to talk to your IT staff to get access over HTTPS to \fBregistry.npmjs.org\fR. +By default, npm installs from the primary npm registry, \fBregistry.npmjs.org\fR. \fBnpm doctor\fR hits a special connection testing endpoint within the registry. This can also be checked with \fBnpm ping\fR. If this check fails, you may be using a proxy that needs to be configured, or may need to talk to your IT staff to get access over HTTPS to \fBregistry.npmjs.org\fR. .P This check is done against whichever registry you've configured (you can see what that is by running \fBnpm config get registry\fR), and if you're using a private registry that doesn't support the \fB/whoami\fR endpoint supported by the primary registry, this check may fail. -.SS "\fBnpm -v\fR" +.SS "\fBChecking npm version\fR" .P While Node.js may come bundled with a particular version of npm, it's the policy of the CLI team that we recommend all users run \fBnpm@latest\fR if they can. As the CLI is maintained by a small team of contributors, there are only resources for a single line of development, so npm's own long-term support releases typically only receive critical security and regression fixes. The team believes that the latest tested version of npm is almost always likely to be the most functional and defect-free version of npm. -.SS "\fBnode -v\fR" +.SS "\fBChecking node version\fR" .P For most users, in most circumstances, the best version of Node will be the latest long-term support (LTS) release. Those of you who want access to new ECMAscript features or bleeding-edge changes to Node's standard library may be running a newer version, and some may be required to run an older version of Node because of enterprise change control policies. That's OK! But in general, the npm team recommends that most users run Node.js LTS. -.SS "\fBnpm config get registry\fR" +.SS "\fBChecking configured npm registry\fR" .P You may be installing from private package registries for your project or company. That's great! Others may be following tutorials or StackOverflow questions in an effort to troubleshoot problems you may be having. Sometimes, this may entail changing the registry you're pointing at. This part of \fBnpm doctor\fR just lets you, and maybe whoever's helping you with support, know that you're not using the default registry. -.SS "\fBwhich git\fR" +.SS "\fBChecking for git executable in PATH\fR" .P While it's documented in the README, it may not be obvious that npm needs Git installed to do many of the things that it does. Also, in some cases \[en] especially on Windows \[en] you may have Git set up in such a way that it's not accessible via your \fBPATH\fR so that npm can find it. This check ensures that Git is available. .SS "Permissions checks" diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1 index 9c8a25d0c9237a..3d4728693455e4 100644 --- a/deps/npm/man/man1/npm-ls.1 +++ b/deps/npm/man/man1/npm-ls.1 @@ -20,7 +20,7 @@ Positional arguments are \fBname@version-range\fR identifiers, which will limit .P .RS 2 .nf -npm@10.5.2 /path/to/npm +npm@10.7.0 /path/to/npm └─┬ init-package-json@0.0.4 └── promzard@0.1.5 .fi diff --git a/deps/npm/man/man1/npm-profile.1 b/deps/npm/man/man1/npm-profile.1 index 401c26f05b2d5c..423167e2efafc4 100644 --- a/deps/npm/man/man1/npm-profile.1 +++ b/deps/npm/man/man1/npm-profile.1 @@ -24,27 +24,16 @@ Change your profile information on the registry. Note that this command depends .P .RS 2 .nf -+-----------------+---------------------------+ -| name | example | -+-----------------+---------------------------+ -| email | me@example.com (verified) | -+-----------------+---------------------------+ -| two factor auth | auth-and-writes | -+-----------------+---------------------------+ -| fullname | Example User | -+-----------------+---------------------------+ -| homepage | | -+-----------------+---------------------------+ -| freenode | | -+-----------------+---------------------------+ -| twitter | | -+-----------------+---------------------------+ -| github | | -+-----------------+---------------------------+ -| created | 2015-02-26T01:38:35.892Z | -+-----------------+---------------------------+ -| updated | 2017-10-02T21:29:45.922Z | -+-----------------+---------------------------+ +name: example +email: e@example.com (verified) +two-factor auth: auth-and-writes +fullname: Example User +homepage: +freenode: +twitter: +github: +created: 2015-02-26T01:38:35.892Z +updated: 2017-10-02T21:29:45.922Z .fi .RE .RS 0 diff --git a/deps/npm/man/man1/npm-search.1 b/deps/npm/man/man1/npm-search.1 index 7927e562bf9e59..041bd1113010f5 100644 --- a/deps/npm/man/man1/npm-search.1 +++ b/deps/npm/man/man1/npm-search.1 @@ -5,7 +5,7 @@ .P .RS 2 .nf -npm search \[lB]search terms ...\[rB] +npm search \[lB] ...\[rB] aliases: find, s, se .fi @@ -22,16 +22,6 @@ Search also allows targeting of maintainers in search results, by prefixing thei .P If a term starts with \fB/\fR, then it's interpreted as a regular expression and supports standard JavaScript RegExp syntax. In this case search will ignore a trailing \fB/\fR . (Note you must escape or quote many regular expression characters in most shells.) .SS "Configuration" -.SS "\fBlong\fR" -.RS 0 -.IP \(bu 4 -Default: false -.IP \(bu 4 -Type: Boolean -.RE 0 - -.P -Show extended information in \fBls\fR, \fBsearch\fR, and \fBhelp-search\fR. .SS "\fBjson\fR" .RS 0 .IP \(bu 4 diff --git a/deps/npm/man/man1/npm-token.1 b/deps/npm/man/man1/npm-token.1 index 431302c44a7757..2b35907fb49681 100644 --- a/deps/npm/man/man1/npm-token.1 +++ b/deps/npm/man/man1/npm-token.1 @@ -23,23 +23,13 @@ This lets you list, create and revoke authentication tokens. .P .RS 2 .nf -+--------+---------+------------+----------+----------------+ -| id | token | created | read-only | CIDR whitelist | -+--------+---------+------------+----------+----------------+ -| 7f3134 | 1fa9ba… | 2017-10-02 | yes | | -+--------+---------+------------+----------+----------------+ -| c03241 | af7aef… | 2017-10-02 | no | 192.168.0.1/24 | -+--------+---------+------------+----------+----------------+ -| e0cf92 | 3a436a… | 2017-10-02 | no | | -+--------+---------+------------+----------+----------------+ -| 63eb9d | 74ef35… | 2017-09-28 | no | | -+--------+---------+------------+----------+----------------+ -| 2daaa8 | cbad5f… | 2017-09-26 | no | | -+--------+---------+------------+----------+----------------+ -| 68c2fe | 127e51… | 2017-09-23 | no | | -+--------+---------+------------+----------+----------------+ -| 6334e1 | 1dadd1… | 2017-09-23 | no | | -+--------+---------+------------+----------+----------------+ +Read only token npm_1f… with id 7f3134 created 2017-10-21 + +Publish token npm_af… with id c03241 created 2017-10-02 +with IP Whitelist: 192.168.0.1/24 + +Publish token npm_… with id e0cf92 created 2017-10-02 + .fi .RE .RS 0 @@ -52,15 +42,7 @@ Currently, the cli can not generate automation tokens. Please refer to the \fBdo .P .RS 2 .nf -+----------------+--------------------------------------+ -| token | a73c9572-f1b9-8983-983d-ba3ac3cc913d | -+----------------+--------------------------------------+ -| cidr_whitelist | | -+----------------+--------------------------------------+ -| readonly | false | -+----------------+--------------------------------------+ -| created | 2017-10-02T07:52:24.838Z | -+----------------+--------------------------------------+ +Created publish token a73c9572-f1b9-8983-983d-ba3ac3cc913d .fi .RE .RS 0 diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1 index 0df8bb7e2a1962..6fb97e843320ea 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -12,7 +12,7 @@ npm Note: This command is unaware of workspaces. .SS "Version" .P -10.5.2 +10.7.0 .SS "Description" .P npm is the package manager for the Node JavaScript platform. It puts modules in place so that node can find them, and manages dependency conflicts intelligently. diff --git a/deps/npm/man/man5/npm-json.5 b/deps/npm/man/man5/npm-json.5 index 69dcb58aa1b1ef..f4d903e2b114cf 100644 --- a/deps/npm/man/man5/npm-json.5 +++ b/deps/npm/man/man5/npm-json.5 @@ -840,6 +840,8 @@ If you need to make specific changes to dependencies of your dependencies, for e .P Overrides provide a way to replace a package in your dependency tree with another version, or another package entirely. These changes can be scoped as specific or as vague as desired. .P +Overrides are only considered in the root \fBpackage.json\fR file for a project. Overrides in installed dependencies (including npm help workspaces) are not considered in dependency tree resolution. Published packages may dictate their resolutions by pinning dependencies or using an \fB\fBnpm-shrinkwrap.json\fR\fR \fI\(la/configuring-npm/npm-shrinkwrap-json\(ra\fR file. +.P To make sure the package \fBfoo\fR is always installed as version \fB1.0.0\fR no matter what version your dependencies rely on: .P .RS 2 diff --git a/deps/npm/man/man5/package-json.5 b/deps/npm/man/man5/package-json.5 index 69dcb58aa1b1ef..f4d903e2b114cf 100644 --- a/deps/npm/man/man5/package-json.5 +++ b/deps/npm/man/man5/package-json.5 @@ -840,6 +840,8 @@ If you need to make specific changes to dependencies of your dependencies, for e .P Overrides provide a way to replace a package in your dependency tree with another version, or another package entirely. These changes can be scoped as specific or as vague as desired. .P +Overrides are only considered in the root \fBpackage.json\fR file for a project. Overrides in installed dependencies (including npm help workspaces) are not considered in dependency tree resolution. Published packages may dictate their resolutions by pinning dependencies or using an \fB\fBnpm-shrinkwrap.json\fR\fR \fI\(la/configuring-npm/npm-shrinkwrap-json\(ra\fR file. +.P To make sure the package \fBfoo\fR is always installed as version \fB1.0.0\fR no matter what version your dependencies rely on: .P .RS 2 diff --git a/deps/npm/man/man5/package-lock-json.5 b/deps/npm/man/man5/package-lock-json.5 index 426901d95437d9..c6a92af27f189c 100644 --- a/deps/npm/man/man5/package-lock-json.5 +++ b/deps/npm/man/man5/package-lock-json.5 @@ -19,6 +19,8 @@ Optimize the installation process by allowing npm to skip repeated metadata reso As of npm v7, lockfiles include enough information to gain a complete picture of the package tree, reducing the need to read \fBpackage.json\fR files, and allowing for significant performance improvements. .RE 0 +.P +When \fBnpm\fR creates or updates \fBpackage-lock.json\fR, it will infer line endings and indentation from \fBpackage.json\fR so that the formatting of both files matches. .SS "\fBpackage-lock.json\fR vs \fBnpm-shrinkwrap.json\fR" .P Both of these files have the same format, and perform similar functions in the root of a project. diff --git a/deps/npm/node_modules/@colors/colors/LICENSE b/deps/npm/node_modules/@colors/colors/LICENSE deleted file mode 100644 index 6b86056199d2ac..00000000000000 --- a/deps/npm/node_modules/@colors/colors/LICENSE +++ /dev/null @@ -1,26 +0,0 @@ -MIT License - -Original Library - - Copyright (c) Marak Squires - -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 -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/deps/npm/node_modules/@colors/colors/examples/normal-usage.js b/deps/npm/node_modules/@colors/colors/examples/normal-usage.js deleted file mode 100644 index c4515653e288d7..00000000000000 --- a/deps/npm/node_modules/@colors/colors/examples/normal-usage.js +++ /dev/null @@ -1,82 +0,0 @@ -var colors = require('../lib/index'); - -console.log('First some yellow text'.yellow); - -console.log('Underline that text'.yellow.underline); - -console.log('Make it bold and red'.red.bold); - -console.log(('Double Raindows All Day Long').rainbow); - -console.log('Drop the bass'.trap); - -console.log('DROP THE RAINBOW BASS'.trap.rainbow); - -// styles not widely supported -console.log('Chains are also cool.'.bold.italic.underline.red); - -// styles not widely supported -console.log('So '.green + 'are'.underline + ' ' + 'inverse'.inverse - + ' styles! '.yellow.bold); -console.log('Zebras are so fun!'.zebra); - -// -// Remark: .strikethrough may not work with Mac OS Terminal App -// -console.log('This is ' + 'not'.strikethrough + ' fun.'); - -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'); - -// -// Custom themes -// -console.log('Generic logging theme as JSON'.green.bold.underline); -// Load theme with JSON literal -colors.setTheme({ - silly: 'rainbow', - input: 'grey', - verbose: 'cyan', - prompt: 'grey', - info: 'green', - data: 'grey', - help: 'cyan', - warn: 'yellow', - debug: 'blue', - error: 'red', -}); - -// outputs red text -console.log('this is an error'.error); - -// outputs yellow text -console.log('this is a warning'.warn); - -// outputs grey text -console.log('this is an input'.input); - -console.log('Generic logging theme as file'.green.bold.underline); - -// Load a theme from file -try { - colors.setTheme(require(__dirname + '/../themes/generic-logging.js')); -} catch (err) { - console.log(err); -} - -// outputs red text -console.log('this is an error'.error); - -// outputs yellow text -console.log('this is a warning'.warn); - -// outputs grey text -console.log('this is an input'.input); - -// console.log("Don't summon".zalgo) diff --git a/deps/npm/node_modules/@colors/colors/examples/safe-string.js b/deps/npm/node_modules/@colors/colors/examples/safe-string.js deleted file mode 100644 index ed5f4ca468e10f..00000000000000 --- a/deps/npm/node_modules/@colors/colors/examples/safe-string.js +++ /dev/null @@ -1,78 +0,0 @@ -var colors = require('../safe'); - -console.log(colors.yellow('First some yellow text')); - -console.log(colors.yellow.underline('Underline that text')); - -console.log(colors.red.bold('Make it bold and red')); - -console.log(colors.rainbow('Double Raindows All Day Long')); - -console.log(colors.trap('Drop the bass')); - -console.log(colors.rainbow(colors.trap('DROP THE RAINBOW BASS'))); - -// styles not widely supported -console.log(colors.bold.italic.underline.red('Chains are also cool.')); - -// styles not widely supported -console.log(colors.green('So ') + colors.underline('are') + ' ' - + colors.inverse('inverse') + colors.yellow.bold(' styles! ')); - -console.log(colors.zebra('Zebras are so fun!')); - -console.log('This is ' + colors.strikethrough('not') + ' fun.'); - - -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'); - -// -// Custom themes -// -// console.log('Generic logging theme as JSON'.green.bold.underline); -// Load theme with JSON literal -colors.setTheme({ - silly: 'rainbow', - input: 'blue', - verbose: 'cyan', - prompt: 'grey', - info: 'green', - data: 'grey', - help: 'cyan', - warn: 'yellow', - debug: 'blue', - error: 'red', -}); - -// outputs red text -console.log(colors.error('this is an error')); - -// outputs yellow text -console.log(colors.warn('this is a warning')); - -// outputs blue text -console.log(colors.input('this is an input')); - - -// console.log('Generic logging theme as file'.green.bold.underline); - -// Load a theme from file -colors.setTheme(require(__dirname + '/../themes/generic-logging.js')); - -// outputs red text -console.log(colors.error('this is an error')); - -// outputs yellow text -console.log(colors.warn('this is a warning')); - -// outputs grey text -console.log(colors.input('this is an input')); - -// console.log(colors.zalgo("Don't summon him")) diff --git a/deps/npm/node_modules/@colors/colors/lib/colors.js b/deps/npm/node_modules/@colors/colors/lib/colors.js deleted file mode 100644 index d9fb08762fde51..00000000000000 --- a/deps/npm/node_modules/@colors/colors/lib/colors.js +++ /dev/null @@ -1,211 +0,0 @@ -/* - -The MIT License (MIT) - -Original Library - - Copyright (c) Marak Squires - -Additional functionality - - Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -var colors = {}; -module['exports'] = colors; - -colors.themes = {}; - -var util = require('util'); -var ansiStyles = colors.styles = require('./styles'); -var defineProps = Object.defineProperties; -var newLineRegex = new RegExp(/[\r\n]+/g); - -colors.supportsColor = require('./system/supports-colors').supportsColor; - -if (typeof colors.enabled === 'undefined') { - colors.enabled = colors.supportsColor() !== false; -} - -colors.enable = function() { - colors.enabled = true; -}; - -colors.disable = function() { - colors.enabled = false; -}; - -colors.stripColors = colors.strip = function(str) { - return ('' + str).replace(/\x1B\[\d+m/g, ''); -}; - -// eslint-disable-next-line no-unused-vars -var stylize = colors.stylize = function stylize(str, style) { - if (!colors.enabled) { - return str+''; - } - - var styleMap = ansiStyles[style]; - - // Stylize should work for non-ANSI styles, too - 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); - } - - return styleMap.open + str + styleMap.close; -}; - -var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; -var escapeStringRegexp = function(str) { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); - } - return str.replace(matchOperatorsRe, '\\$&'); -}; - -function build(_styles) { - var builder = function builder() { - return applyStyle.apply(builder, arguments); - }; - builder._styles = _styles; - // __proto__ is used because we must return a function, but there is - // no way to create a function with a different prototype. - builder.__proto__ = proto; - return builder; -} - -var styles = (function() { - var ret = {}; - ansiStyles.grey = ansiStyles.gray; - Object.keys(ansiStyles).forEach(function(key) { - ansiStyles[key].closeRe = - new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); - ret[key] = { - get: function() { - return build(this._styles.concat(key)); - }, - }; - }); - return ret; -})(); - -var proto = defineProps(function colors() {}, styles); - -function applyStyle() { - var args = Array.prototype.slice.call(arguments); - - var str = args.map(function(arg) { - // Use weak equality check so we can colorize null/undefined in safe mode - if (arg != null && arg.constructor === String) { - return arg; - } else { - return util.inspect(arg); - } - }).join(' '); - - if (!colors.enabled || !str) { - return str; - } - - var newLinesPresent = str.indexOf('\n') != -1; - - var nestedStyles = this._styles; - - var i = nestedStyles.length; - while (i--) { - var code = ansiStyles[nestedStyles[i]]; - str = code.open + str.replace(code.closeRe, code.open) + code.close; - if (newLinesPresent) { - str = str.replace(newLineRegex, function(match) { - return code.close + match + code.open; - }); - } - } - - return str; -} - -colors.setTheme = function(theme) { - if (typeof theme === 'string') { - console.log('colors.setTheme now only accepts an object, not a string. ' + - 'If you are trying to set a theme from a file, it is now your (the ' + - 'caller\'s) responsibility to require the file. The old syntax ' + - 'looked like colors.setTheme(__dirname + ' + - '\'/../themes/generic-logging.js\'); The new syntax looks like '+ - 'colors.setTheme(require(__dirname + ' + - '\'/../themes/generic-logging.js\'));'); - return; - } - for (var style in theme) { - (function(style) { - colors[style] = function(str) { - if (typeof theme[style] === 'object') { - var out = str; - for (var i in theme[style]) { - out = colors[theme[style][i]](out); - } - return out; - } - return colors[theme[style]](str); - }; - })(style); - } -}; - -function init() { - var ret = {}; - Object.keys(styles).forEach(function(name) { - ret[name] = { - get: function() { - return build([name]); - }, - }; - }); - return ret; -} - -var sequencer = function sequencer(map, str) { - var exploded = str.split(''); - exploded = exploded.map(map); - return exploded.join(''); -}; - -// custom formatter methods -colors.trap = require('./custom/trap'); -colors.zalgo = require('./custom/zalgo'); - -// maps -colors.maps = {}; -colors.maps.america = require('./maps/america')(colors); -colors.maps.zebra = require('./maps/zebra')(colors); -colors.maps.rainbow = require('./maps/rainbow')(colors); -colors.maps.random = require('./maps/random')(colors); - -for (var map in colors.maps) { - (function(map) { - colors[map] = function(str) { - return sequencer(colors.maps[map], str); - }; - })(map); -} - -defineProps(colors, init()); diff --git a/deps/npm/node_modules/@colors/colors/lib/custom/trap.js b/deps/npm/node_modules/@colors/colors/lib/custom/trap.js deleted file mode 100644 index fbccf88dede0b8..00000000000000 --- a/deps/npm/node_modules/@colors/colors/lib/custom/trap.js +++ /dev/null @@ -1,46 +0,0 @@ -module['exports'] = function runTheTrap(text, options) { - var result = ''; - text = text || 'Run the trap, drop the bass'; - text = text.split(''); - var trap = { - a: ['\u0040', '\u0104', '\u023a', '\u0245', '\u0394', '\u039b', '\u0414'], - b: ['\u00df', '\u0181', '\u0243', '\u026e', '\u03b2', '\u0e3f'], - c: ['\u00a9', '\u023b', '\u03fe'], - d: ['\u00d0', '\u018a', '\u0500', '\u0501', '\u0502', '\u0503'], - e: ['\u00cb', '\u0115', '\u018e', '\u0258', '\u03a3', '\u03be', '\u04bc', - '\u0a6c'], - f: ['\u04fa'], - g: ['\u0262'], - h: ['\u0126', '\u0195', '\u04a2', '\u04ba', '\u04c7', '\u050a'], - i: ['\u0f0f'], - j: ['\u0134'], - k: ['\u0138', '\u04a0', '\u04c3', '\u051e'], - l: ['\u0139'], - m: ['\u028d', '\u04cd', '\u04ce', '\u0520', '\u0521', '\u0d69'], - n: ['\u00d1', '\u014b', '\u019d', '\u0376', '\u03a0', '\u048a'], - o: ['\u00d8', '\u00f5', '\u00f8', '\u01fe', '\u0298', '\u047a', '\u05dd', - '\u06dd', '\u0e4f'], - p: ['\u01f7', '\u048e'], - q: ['\u09cd'], - r: ['\u00ae', '\u01a6', '\u0210', '\u024c', '\u0280', '\u042f'], - s: ['\u00a7', '\u03de', '\u03df', '\u03e8'], - t: ['\u0141', '\u0166', '\u0373'], - u: ['\u01b1', '\u054d'], - v: ['\u05d8'], - w: ['\u0428', '\u0460', '\u047c', '\u0d70'], - x: ['\u04b2', '\u04fe', '\u04fc', '\u04fd'], - y: ['\u00a5', '\u04b0', '\u04cb'], - z: ['\u01b5', '\u0240'], - }; - text.forEach(function(c) { - c = c.toLowerCase(); - var chars = trap[c] || [' ']; - var rand = Math.floor(Math.random() * chars.length); - if (typeof trap[c] !== 'undefined') { - result += trap[c][rand]; - } else { - result += c; - } - }); - return result; -}; diff --git a/deps/npm/node_modules/@colors/colors/lib/custom/zalgo.js b/deps/npm/node_modules/@colors/colors/lib/custom/zalgo.js deleted file mode 100644 index 01bdd2b802f626..00000000000000 --- a/deps/npm/node_modules/@colors/colors/lib/custom/zalgo.js +++ /dev/null @@ -1,109 +0,0 @@ -// please no -module['exports'] = function zalgo(text, options) { - text = text || ' he is here '; - var soul = { - 'up': [ - '̍', '̎', '̄', '̅', - '̿', '̑', '̆', '̐', - '͒', '͗', '͑', '̇', - '̈', '̊', '͂', '̓', - '̈', '͊', '͋', '͌', - '̃', '̂', '̌', '͐', - '̀', '́', '̋', '̏', - '̒', '̓', '̔', '̽', - '̉', 'ͣ', 'ͤ', 'ͥ', - 'ͦ', 'ͧ', 'ͨ', 'ͩ', - 'ͪ', 'ͫ', 'ͬ', 'ͭ', - 'ͮ', 'ͯ', '̾', '͛', - '͆', '̚', - ], - 'down': [ - '̖', '̗', '̘', '̙', - '̜', '̝', '̞', '̟', - '̠', '̤', '̥', '̦', - '̩', '̪', '̫', '̬', - '̭', '̮', '̯', '̰', - '̱', '̲', '̳', '̹', - '̺', '̻', '̼', 'ͅ', - '͇', '͈', '͉', '͍', - '͎', '͓', '͔', '͕', - '͖', '͙', '͚', '̣', - ], - 'mid': [ - '̕', '̛', '̀', '́', - '͘', '̡', '̢', '̧', - '̨', '̴', '̵', '̶', - '͜', '͝', '͞', - '͟', '͠', '͢', '̸', - '̷', '͡', ' ҉', - ], - }; - var all = [].concat(soul.up, soul.down, soul.mid); - - function randomNumber(range) { - var r = Math.floor(Math.random() * range); - return r; - } - - function isChar(character) { - var bool = false; - all.filter(function(i) { - bool = (i === character); - }); - return bool; - } - - - function heComes(text, options) { - var result = ''; - var counts; - var l; - options = options || {}; - options['up'] = - typeof options['up'] !== 'undefined' ? options['up'] : true; - options['mid'] = - typeof options['mid'] !== 'undefined' ? options['mid'] : true; - options['down'] = - typeof options['down'] !== 'undefined' ? options['down'] : true; - options['size'] = - typeof options['size'] !== 'undefined' ? options['size'] : 'maxi'; - text = text.split(''); - for (l in text) { - if (isChar(l)) { - continue; - } - result = result + text[l]; - counts = {'up': 0, 'down': 0, 'mid': 0}; - switch (options.size) { - case 'mini': - counts.up = randomNumber(8); - counts.mid = randomNumber(2); - counts.down = randomNumber(8); - break; - case 'maxi': - counts.up = randomNumber(16) + 3; - counts.mid = randomNumber(4) + 1; - counts.down = randomNumber(64) + 3; - break; - default: - counts.up = randomNumber(8) + 1; - counts.mid = randomNumber(6) / 2; - counts.down = randomNumber(8) + 1; - break; - } - - var arr = ['up', 'mid', 'down']; - for (var d in arr) { - var index = arr[d]; - for (var i = 0; i <= counts[index]; i++) { - if (options[index]) { - result = result + soul[index][randomNumber(soul[index].length)]; - } - } - } - } - return result; - } - // don't summon him - return heComes(text, options); -}; diff --git a/deps/npm/node_modules/@colors/colors/lib/extendStringPrototype.js b/deps/npm/node_modules/@colors/colors/lib/extendStringPrototype.js deleted file mode 100644 index 46fd386a915a67..00000000000000 --- a/deps/npm/node_modules/@colors/colors/lib/extendStringPrototype.js +++ /dev/null @@ -1,110 +0,0 @@ -var colors = require('./colors'); - -module['exports'] = function() { - // - // Extends prototype of native string object to allow for "foo".red syntax - // - var addProperty = function(color, func) { - String.prototype.__defineGetter__(color, func); - }; - - addProperty('strip', function() { - return colors.strip(this); - }); - - addProperty('stripColors', function() { - return colors.strip(this); - }); - - addProperty('trap', function() { - return colors.trap(this); - }); - - addProperty('zalgo', function() { - return colors.zalgo(this); - }); - - addProperty('zebra', function() { - return colors.zebra(this); - }); - - addProperty('rainbow', function() { - return colors.rainbow(this); - }); - - addProperty('random', function() { - return colors.random(this); - }); - - addProperty('america', function() { - return colors.america(this); - }); - - // - // Iterate through all default styles and colors - // - var x = Object.keys(colors.styles); - x.forEach(function(style) { - addProperty(style, function() { - return colors.stylize(this, style); - }); - }); - - function applyTheme(theme) { - // - // Remark: This is a list of methods that exist - // on String that you should not overwrite. - // - var stringPrototypeBlacklist = [ - '__defineGetter__', '__defineSetter__', '__lookupGetter__', - '__lookupSetter__', 'charAt', 'constructor', 'hasOwnProperty', - 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', - 'valueOf', 'charCodeAt', 'indexOf', 'lastIndexOf', 'length', - 'localeCompare', 'match', 'repeat', 'replace', 'search', 'slice', - 'split', 'substring', 'toLocaleLowerCase', 'toLocaleUpperCase', - 'toLowerCase', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', - ]; - - Object.keys(theme).forEach(function(prop) { - if (stringPrototypeBlacklist.indexOf(prop) !== -1) { - console.log('warn: '.red + ('String.prototype' + prop).magenta + - ' is probably something you don\'t want to override. ' + - 'Ignoring style name'); - } else { - if (typeof(theme[prop]) === 'string') { - colors[prop] = colors[theme[prop]]; - addProperty(prop, function() { - return colors[prop](this); - }); - } else { - var themePropApplicator = function(str) { - var ret = str || this; - for (var t = 0; t < theme[prop].length; t++) { - ret = colors[theme[prop][t]](ret); - } - return ret; - }; - addProperty(prop, themePropApplicator); - colors[prop] = function(str) { - return themePropApplicator(str); - }; - } - } - }); - } - - colors.setTheme = function(theme) { - if (typeof theme === 'string') { - console.log('colors.setTheme now only accepts an object, not a string. ' + - 'If you are trying to set a theme from a file, it is now your (the ' + - 'caller\'s) responsibility to require the file. The old syntax ' + - 'looked like colors.setTheme(__dirname + ' + - '\'/../themes/generic-logging.js\'); The new syntax looks like '+ - 'colors.setTheme(require(__dirname + ' + - '\'/../themes/generic-logging.js\'));'); - return; - } else { - applyTheme(theme); - } - }; -}; diff --git a/deps/npm/node_modules/@colors/colors/lib/index.js b/deps/npm/node_modules/@colors/colors/lib/index.js deleted file mode 100644 index 9df5ab7df30770..00000000000000 --- a/deps/npm/node_modules/@colors/colors/lib/index.js +++ /dev/null @@ -1,13 +0,0 @@ -var colors = require('./colors'); -module['exports'] = colors; - -// Remark: By default, colors will add style properties to String.prototype. -// -// If you don't wish to extend String.prototype, you can do this instead and -// native String will not be touched: -// -// var colors = require('colors/safe); -// colors.red("foo") -// -// -require('./extendStringPrototype')(); diff --git a/deps/npm/node_modules/@colors/colors/lib/maps/america.js b/deps/npm/node_modules/@colors/colors/lib/maps/america.js deleted file mode 100644 index dc96903328989f..00000000000000 --- a/deps/npm/node_modules/@colors/colors/lib/maps/america.js +++ /dev/null @@ -1,10 +0,0 @@ -module['exports'] = function(colors) { - return function(letter, i, exploded) { - if (letter === ' ') return letter; - switch (i%3) { - case 0: return colors.red(letter); - case 1: return colors.white(letter); - case 2: return colors.blue(letter); - } - }; -}; diff --git a/deps/npm/node_modules/@colors/colors/lib/maps/rainbow.js b/deps/npm/node_modules/@colors/colors/lib/maps/rainbow.js deleted file mode 100644 index 874508da8ed17e..00000000000000 --- a/deps/npm/node_modules/@colors/colors/lib/maps/rainbow.js +++ /dev/null @@ -1,11 +0,0 @@ -module['exports'] = function(colors) { - // RoY G BiV - var rainbowColors = ['red', 'yellow', 'green', 'blue', 'magenta']; - return function(letter, i, exploded) { - if (letter === ' ') { - return letter; - } else { - return colors[rainbowColors[i++ % rainbowColors.length]](letter); - } - }; -}; diff --git a/deps/npm/node_modules/@colors/colors/lib/maps/random.js b/deps/npm/node_modules/@colors/colors/lib/maps/random.js deleted file mode 100644 index 3d82a39ec0fab4..00000000000000 --- a/deps/npm/node_modules/@colors/colors/lib/maps/random.js +++ /dev/null @@ -1,11 +0,0 @@ -module['exports'] = function(colors) { - var available = ['underline', 'inverse', 'grey', 'yellow', 'red', 'green', - 'blue', 'white', 'cyan', 'magenta', 'brightYellow', 'brightRed', - 'brightGreen', 'brightBlue', 'brightWhite', 'brightCyan', 'brightMagenta']; - return function(letter, i, exploded) { - return letter === ' ' ? letter : - colors[ - available[Math.round(Math.random() * (available.length - 2))] - ](letter); - }; -}; diff --git a/deps/npm/node_modules/@colors/colors/lib/maps/zebra.js b/deps/npm/node_modules/@colors/colors/lib/maps/zebra.js deleted file mode 100644 index fa73623544a82c..00000000000000 --- a/deps/npm/node_modules/@colors/colors/lib/maps/zebra.js +++ /dev/null @@ -1,5 +0,0 @@ -module['exports'] = function(colors) { - return function(letter, i, exploded) { - return i % 2 === 0 ? letter : colors.inverse(letter); - }; -}; diff --git a/deps/npm/node_modules/@colors/colors/lib/styles.js b/deps/npm/node_modules/@colors/colors/lib/styles.js deleted file mode 100644 index 011dafd8c28f70..00000000000000 --- a/deps/npm/node_modules/@colors/colors/lib/styles.js +++ /dev/null @@ -1,95 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -var styles = {}; -module['exports'] = styles; - -var codes = { - reset: [0, 0], - - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29], - - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - gray: [90, 39], - grey: [90, 39], - - brightRed: [91, 39], - brightGreen: [92, 39], - brightYellow: [93, 39], - brightBlue: [94, 39], - brightMagenta: [95, 39], - brightCyan: [96, 39], - brightWhite: [97, 39], - - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], - bgGray: [100, 49], - bgGrey: [100, 49], - - bgBrightRed: [101, 49], - bgBrightGreen: [102, 49], - bgBrightYellow: [103, 49], - bgBrightBlue: [104, 49], - bgBrightMagenta: [105, 49], - bgBrightCyan: [106, 49], - bgBrightWhite: [107, 49], - - // legacy styles for colors pre v1.0.0 - blackBG: [40, 49], - redBG: [41, 49], - greenBG: [42, 49], - yellowBG: [43, 49], - blueBG: [44, 49], - magentaBG: [45, 49], - cyanBG: [46, 49], - whiteBG: [47, 49], - -}; - -Object.keys(codes).forEach(function(key) { - var val = codes[key]; - var style = styles[key] = []; - style.open = '\u001b[' + val[0] + 'm'; - style.close = '\u001b[' + val[1] + 'm'; -}); diff --git a/deps/npm/node_modules/@colors/colors/lib/system/has-flag.js b/deps/npm/node_modules/@colors/colors/lib/system/has-flag.js deleted file mode 100644 index a347dd4d7a697e..00000000000000 --- a/deps/npm/node_modules/@colors/colors/lib/system/has-flag.js +++ /dev/null @@ -1,35 +0,0 @@ -/* -MIT License - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -'use strict'; - -module.exports = function(flag, argv) { - argv = argv || process.argv; - - var terminatorPos = argv.indexOf('--'); - var prefix = /^-{1,2}/.test(flag) ? '' : '--'; - var pos = argv.indexOf(prefix + flag); - - return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); -}; diff --git a/deps/npm/node_modules/@colors/colors/lib/system/supports-colors.js b/deps/npm/node_modules/@colors/colors/lib/system/supports-colors.js deleted file mode 100644 index f1f9c8ff3da284..00000000000000 --- a/deps/npm/node_modules/@colors/colors/lib/system/supports-colors.js +++ /dev/null @@ -1,151 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -'use strict'; - -var os = require('os'); -var hasFlag = require('./has-flag.js'); - -var env = process.env; - -var forceColor = void 0; -if (hasFlag('no-color') || hasFlag('no-colors') || hasFlag('color=false')) { - forceColor = false; -} else if (hasFlag('color') || hasFlag('colors') || hasFlag('color=true') - || hasFlag('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env) { - forceColor = env.FORCE_COLOR.length === 0 - || parseInt(env.FORCE_COLOR, 10) !== 0; -} - -function translateLevel(level) { - if (level === 0) { - return false; - } - - return { - level: level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3, - }; -} - -function supportsColor(stream) { - if (forceColor === false) { - return 0; - } - - if (hasFlag('color=16m') || hasFlag('color=full') - || hasFlag('color=truecolor')) { - return 3; - } - - if (hasFlag('color=256')) { - return 2; - } - - if (stream && !stream.isTTY && forceColor !== true) { - return 0; - } - - var min = forceColor ? 1 : 0; - - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first - // Windows release that supports 256 colors. Windows 10 build 14931 is the - // first release that supports 16m/TrueColor. - var osRelease = os.release().split('.'); - if (Number(process.versions.node.split('.')[0]) >= 8 - && Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - - return 1; - } - - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(function(sign) { - return sign in env; - }) || env.CI_NAME === 'codeship') { - return 1; - } - - return min; - } - - if ('TEAMCITY_VERSION' in env) { - return (/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0 - ); - } - - if ('TERM_PROGRAM' in env) { - var version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Hyper': - return 3; - case 'Apple_Terminal': - return 2; - // No default - } - } - - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } - - if ('COLORTERM' in env) { - return 1; - } - - if (env.TERM === 'dumb') { - return min; - } - - return min; -} - -function getSupportLevel(stream) { - var level = supportsColor(stream); - return translateLevel(level); -} - -module.exports = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr), -}; diff --git a/deps/npm/node_modules/@colors/colors/package.json b/deps/npm/node_modules/@colors/colors/package.json deleted file mode 100644 index cb87f20953886a..00000000000000 --- a/deps/npm/node_modules/@colors/colors/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "@colors/colors", - "description": "get colors in your node.js console", - "version": "1.5.0", - "author": "DABH", - "contributors": [ - { - "name": "DABH", - "url": "https://github.com/DABH" - } - ], - "homepage": "https://github.com/DABH/colors.js", - "bugs": "https://github.com/DABH/colors.js/issues", - "keywords": [ - "ansi", - "terminal", - "colors" - ], - "repository": { - "type": "git", - "url": "http://github.com/DABH/colors.js.git" - }, - "license": "MIT", - "scripts": { - "lint": "eslint . --fix", - "test": "export FORCE_COLOR=1 && node tests/basic-test.js && node tests/safe-test.js" - }, - "engines": { - "node": ">=0.1.90" - }, - "main": "lib/index.js", - "files": [ - "examples", - "lib", - "LICENSE", - "safe.js", - "themes", - "index.d.ts", - "safe.d.ts" - ], - "devDependencies": { - "eslint": "^5.2.0", - "eslint-config-google": "^0.11.0" - } -} diff --git a/deps/npm/node_modules/@colors/colors/safe.js b/deps/npm/node_modules/@colors/colors/safe.js deleted file mode 100644 index a013d542464854..00000000000000 --- a/deps/npm/node_modules/@colors/colors/safe.js +++ /dev/null @@ -1,10 +0,0 @@ -// -// Remark: Requiring this file will use the "safe" colors API, -// which will not touch String.prototype. -// -// var colors = require('colors/safe'); -// colors.red("foo") -// -// -var colors = require('./lib/colors'); -module['exports'] = colors; diff --git a/deps/npm/node_modules/@colors/colors/themes/generic-logging.js b/deps/npm/node_modules/@colors/colors/themes/generic-logging.js deleted file mode 100644 index 63adfe4ac31f9a..00000000000000 --- a/deps/npm/node_modules/@colors/colors/themes/generic-logging.js +++ /dev/null @@ -1,12 +0,0 @@ -module['exports'] = { - silly: 'rainbow', - input: 'grey', - verbose: 'cyan', - prompt: 'grey', - info: 'green', - data: 'grey', - help: 'cyan', - warn: 'yellow', - debug: 'blue', - error: 'red', -}; diff --git a/deps/npm/node_modules/@npmcli/arborist/bin/index.js b/deps/npm/node_modules/@npmcli/arborist/bin/index.js index ff356fafab7c34..414c7eb468cd85 100755 --- a/deps/npm/node_modules/@npmcli/arborist/bin/index.js +++ b/deps/npm/node_modules/@npmcli/arborist/bin/index.js @@ -2,6 +2,7 @@ const fs = require('fs') const path = require('path') +const { time } = require('proc-log') const { bin, arb: options } = require('./lib/options') const version = require('../package.json').version @@ -72,11 +73,11 @@ for (const file of commandFiles) { log.info(name, options) - process.emit('time', totalTime) - process.emit('time', scriptTime) + const timeEnd = time.start(totalTime) + const scriptEnd = time.start(scriptTime) return command(options, (result) => { - process.emit('timeEnd', scriptTime) + scriptEnd() return { result, timing: { @@ -95,7 +96,7 @@ for (const file of commandFiles) { return err }) .then((r) => { - process.emit('timeEnd', totalTime) + timeEnd() if (bin.loglevel !== 'silent') { console[process.exitCode ? 'error' : 'log'](r) } diff --git a/deps/npm/node_modules/@npmcli/arborist/bin/lib/logging.js b/deps/npm/node_modules/@npmcli/arborist/bin/lib/logging.js index ffb5544b21463e..f06716735de74c 100644 --- a/deps/npm/node_modules/@npmcli/arborist/bin/lib/logging.js +++ b/deps/npm/node_modules/@npmcli/arborist/bin/lib/logging.js @@ -1,4 +1,4 @@ -const log = require('proc-log') +const { log } = require('proc-log') const fs = require('fs') const { dirname } = require('path') const os = require('os') diff --git a/deps/npm/node_modules/@npmcli/arborist/bin/lib/timers.js b/deps/npm/node_modules/@npmcli/arborist/bin/lib/timers.js index 586dee7806dd0e..a7ec534f5c5a79 100644 --- a/deps/npm/node_modules/@npmcli/arborist/bin/lib/timers.js +++ b/deps/npm/node_modules/@npmcli/arborist/bin/lib/timers.js @@ -4,22 +4,22 @@ const log = require('./logging.js') const timers = new Map() const finished = new Map() -process.on('time', name => { - if (timers.has(name)) { - throw new Error('conflicting timer! ' + name) - } - timers.set(name, process.hrtime.bigint()) -}) - -process.on('timeEnd', name => { - if (!timers.has(name)) { - throw new Error('timer not started! ' + name) - } - const elapsed = Number(process.hrtime.bigint() - timers.get(name)) - timers.delete(name) - finished.set(name, elapsed) - if (options.timing) { - log.info('timeEnd', `${name} ${elapsed / 1e9}s`, log.meta({ force: options.timing === 'always' })) +process.on('time', (level, name) => { + if (level === 'start') { + if (timers.has(name)) { + throw new Error('conflicting timer! ' + name) + } + timers.set(name, process.hrtime.bigint()) + } else if (level === 'end') { + if (!timers.has(name)) { + throw new Error('timer not started! ' + name) + } + const elapsed = Number(process.hrtime.bigint() - timers.get(name)) + timers.delete(name) + finished.set(name, elapsed) + if (options.timing) { + log.info('timeEnd', `${name} ${elapsed / 1e9}s`, log.meta({ force: options.timing === 'always' })) + } } }) diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js b/deps/npm/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js index c5cdc097a9fab7..2e30eb1de76264 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/add-rm-pkg-deps.js @@ -1,6 +1,6 @@ // add and remove dependency specs to/from pkg manifest -const log = require('proc-log') +const { log } = require('proc-log') const localeCompare = require('@isaacs/string-locale-compare')('en') const add = ({ pkg, add, saveBundle, saveType }) => { diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js index 75e4d373259a09..920403d231d6db 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js @@ -11,7 +11,7 @@ const treeCheck = require('../tree-check.js') const { readdirScoped } = require('@npmcli/fs') const { lstat, readlink } = require('fs/promises') const { depth } = require('treeverse') -const log = require('proc-log') +const { log, time } = require('proc-log') const { redact } = require('@npmcli/redact') const { @@ -179,7 +179,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { options.rm = null } - process.emit('time', 'idealTree') + const timeEnd = time.start('idealTree') if (!options.add && !options.rm && !options.update && this.options.global) { throw new Error('global requires add, rm, or update option') @@ -205,7 +205,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { await this.#pruneFailedOptional() await this.#checkEngineAndPlatform() } finally { - process.emit('timeEnd', 'idealTree') + timeEnd() this.finishTracker('idealTree') } @@ -278,7 +278,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { // load the initial tree, either the virtualTree from a shrinkwrap, // or just the root node from a package.json async #initTree () { - process.emit('time', 'idealTree:init') + const timeEnd = time.start('idealTree:init') let root if (this.options.global) { root = await this.#globalRootNode() @@ -356,7 +356,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { // if you want another one, load another copy. this.idealTree = tree this.virtualTree = null - process.emit('timeEnd', 'idealTree:init') + timeEnd() return tree }) } @@ -420,7 +420,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { // process the add/rm requests by modifying the root node, and the // update.names request by queueing nodes dependent on those named. async #applyUserRequests (options) { - process.emit('time', 'idealTree:userRequests') + const timeEnd = time.start('idealTree:userRequests') const tree = this.idealTree.target if (!this.options.workspaces.length) { @@ -436,7 +436,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { await Promise.all(appliedRequests) } - process.emit('timeEnd', 'idealTree:userRequests') + timeEnd() } async #applyUserRequestsToNode (tree, options) { @@ -463,7 +463,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { } const dir = resolve(nm, name) const st = await lstat(dir) - .catch(/* istanbul ignore next */ er => null) + .catch(/* istanbul ignore next */ () => null) if (st && st.isSymbolicLink()) { const target = await readlink(dir) const real = resolve(dirname(dir), target).replace(/#/g, '%23') @@ -691,7 +691,7 @@ module.exports = cls => class IdealTreeBuilder extends cls { // if the lockfile is from node v5 or earlier, then we'll have to reload // all the manifests of everything we encounter. this is costly, but at // least it's just a one-time hit. - process.emit('time', 'idealTree:inflate') + const timeEnd = time.start('idealTree:inflate') // don't warn if we're not gonna actually write it back anyway. const heading = ancient ? 'ancient lockfile' : 'old lockfile' @@ -758,14 +758,14 @@ This is a one-time fix-up, please be patient... meta.originalLockfileVersion = defaultLockfileVersion } this.finishTracker('idealTree:inflate') - process.emit('timeEnd', 'idealTree:inflate') + timeEnd() } // at this point we have a virtual tree with the actual root node's // package deps, which may be partly or entirely incomplete, invalid // or extraneous. #buildDeps () { - process.emit('time', 'idealTree:buildDeps') + const timeEnd = time.start('idealTree:buildDeps') const tree = this.idealTree.target tree.assertRootOverrides() this.#depsQueue.push(tree) @@ -773,15 +773,14 @@ This is a one-time fix-up, please be patient... // in the override list log.silly('idealTree', 'buildDeps') this.addTracker('idealTree', tree.name, '') - return this.#buildDepStep() - .then(() => process.emit('timeEnd', 'idealTree:buildDeps')) + return this.#buildDepStep().then(timeEnd) } async #buildDepStep () { // removes tracker of previous dependency in the queue if (this.#currentDep) { const { location, name } = this.#currentDep - process.emit('timeEnd', `idealTree:${location || '#root'}`) + time.end(`idealTree:${location || '#root'}`) this.finishTracker('idealTree', name, location) this.#currentDep = null } @@ -807,7 +806,7 @@ This is a one-time fix-up, please be patient... this.#depsSeen.add(node) this.#currentDep = node - process.emit('time', `idealTree:${node.location || '#root'}`) + time.start(`idealTree:${node.location || '#root'}`) // if we're loading a _complete_ ideal tree, for a --package-lock-only // installation for example, we have to crack open the tarball and @@ -1025,7 +1024,7 @@ This is a one-time fix-up, please be patient... for (const e of this.#problemEdges(placed)) { promises.push(() => this.#fetchManifest(npa.resolve(e.name, e.spec, fromPath(placed, e))) - .catch(er => null) + .catch(() => null) ) } }, @@ -1274,7 +1273,7 @@ This is a one-time fix-up, please be patient... }) } - #linkFromSpec (name, spec, parent, edge) { + #linkFromSpec (name, spec, parent) { const realpath = spec.fetchSpec const { installLinks, legacyPeerDeps } = this return rpj(realpath + '/package.json').catch(() => ({})).then(pkg => { @@ -1449,7 +1448,7 @@ This is a one-time fix-up, please be patient... } #fixDepFlags () { - process.emit('time', 'idealTree:fixDepFlags') + const timeEnd = time.start('idealTree:fixDepFlags') const metaFromDisk = this.idealTree.meta.loadedFromDisk const flagsSuspect = this[_flagsSuspect] const mutateTree = this.#mutateTree @@ -1496,7 +1495,7 @@ This is a one-time fix-up, please be patient... } } - process.emit('timeEnd', 'idealTree:fixDepFlags') + timeEnd() } #idealTreePrune () { diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/index.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/index.js index 358f3e1b1a7598..ba180f354708a2 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/index.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/index.js @@ -30,7 +30,7 @@ const { resolve } = require('path') const { homedir } = require('os') const { depth } = require('treeverse') const mapWorkspaces = require('@npmcli/map-workspaces') -const log = require('proc-log') +const { log, time } = require('proc-log') const { saveTypeMap } = require('../add-rm-pkg-deps.js') const AuditReport = require('../audit-report.js') @@ -66,7 +66,7 @@ const lockfileVersion = lfv => { class Arborist extends Base { constructor (options = {}) { - process.emit('time', 'arborist:ctor') + const timeEnd = time.start('arborist:ctor') super(options) this.options = { nodeVersion: process.version, @@ -74,20 +74,26 @@ class Arborist extends Base { Arborist: this.constructor, binLinks: 'binLinks' in options ? !!options.binLinks : true, cache: options.cache || `${homedir()}/.npm/_cacache`, + dryRun: !!options.dryRun, + formatPackageLock: 'formatPackageLock' in options ? !!options.formatPackageLock : true, force: !!options.force, global: !!options.global, ignoreScripts: !!options.ignoreScripts, installStrategy: options.global ? 'shallow' : (options.installStrategy ? options.installStrategy : 'hoisted'), lockfileVersion: lockfileVersion(options.lockfileVersion), + packageLockOnly: !!options.packageLockOnly, packumentCache: options.packumentCache || new Map(), path: options.path || '.', rebuildBundle: 'rebuildBundle' in options ? !!options.rebuildBundle : true, replaceRegistryHost: options.replaceRegistryHost, + savePrefix: 'savePrefix' in options ? options.savePrefix : '^', scriptShell: options.scriptShell, workspaces: options.workspaces || [], workspacesEnabled: options.workspacesEnabled !== false, } - // TODO is this even used? If not is that a bug? + // TODO we only ever look at this.options.replaceRegistryHost, not + // this.replaceRegistryHost. Defaulting needs to be written back to + // this.options to work properly this.replaceRegistryHost = this.options.replaceRegistryHost = (!this.options.replaceRegistryHost || this.options.replaceRegistryHost === 'npmjs') ? 'registry.npmjs.org' : this.options.replaceRegistryHost @@ -96,8 +102,9 @@ class Arborist extends Base { throw new Error(`Invalid saveType ${options.saveType}`) } this.cache = resolve(this.options.cache) + this.diff = null this.path = resolve(this.options.path) - process.emit('timeEnd', 'arborist:ctor') + timeEnd() } // TODO: We should change these to static functions instead @@ -223,7 +230,7 @@ class Arborist extends Base { // XXX: deprecate separate method options objects. options = { ...this.options, ...options } - process.emit('time', 'audit') + const timeEnd = time.start('audit') let tree if (options.packageLock === false) { // build ideal tree @@ -246,10 +253,28 @@ class Arborist extends Base { } this.auditReport = await AuditReport.load(tree, options) const ret = options.fix ? this.reify(options) : this.auditReport - process.emit('timeEnd', 'audit') + timeEnd() this.finishTracker('audit') return ret } + + async dedupe (options = {}) { + // allow the user to set options on the ctor as well. + // XXX: deprecate separate method options objects. + options = { ...this.options, ...options } + const tree = await this.loadVirtual().catch(() => this.loadActual()) + const names = [] + for (const name of tree.inventory.query('name')) { + if (tree.inventory.query('name', name).size > 1) { + names.push(name) + } + } + return this.reify({ + ...options, + preferDedupe: true, + update: { names }, + }) + } } module.exports = Arborist diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/isolated-reifier.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/isolated-reifier.js index f4f1bb8e443624..1e60d0f696b26d 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/isolated-reifier.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/isolated-reifier.js @@ -1,7 +1,7 @@ const _makeIdealGraph = Symbol('makeIdealGraph') const _createIsolatedTree = Symbol.for('createIsolatedTree') const _createBundledTree = Symbol('createBundledTree') -const fs = require('fs') +const { mkdirSync } = require('fs') const pacote = require('pacote') const { join } = require('path') const { depth } = require('treeverse') @@ -108,7 +108,7 @@ module.exports = cls => class IsolatedReifier extends cls { '.store', `${node.name}@${node.version}` ) - fs.mkdirSync(dir, { recursive: true }) + mkdirSync(dir, { recursive: true }) // TODO this approach feels wrong // and shouldn't be necessary for shrinkwraps await pacote.extract(node.resolved, dir, { @@ -212,7 +212,7 @@ module.exports = cls => class IsolatedReifier extends cls { return { edges, nodes } } - async [_createIsolatedTree] (idealTree) { + async [_createIsolatedTree] () { await this[_makeIdealGraph](this.options) const proxiedIdealTree = this.idealGraph diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-actual.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-actual.js index 3ab5f5983768df..81c1bd11327753 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-actual.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-actual.js @@ -336,8 +336,8 @@ module.exports = cls => class ActualLoader extends cls { await this.#loadFSChildren(node.target) return Promise.all( [...node.target.children.entries()] - .filter(([name, kid]) => !did.has(kid.realpath)) - .map(([name, kid]) => this.#loadFSTree(kid)) + .filter(([, kid]) => !did.has(kid.realpath)) + .map(([, kid]) => this.#loadFSTree(kid)) ) } } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js index 9b681a47a83587..d96d4adc88a702 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js @@ -283,7 +283,7 @@ module.exports = cls => class VirtualLoader extends cls { return node } - #loadLink (location, targetLoc, target, meta) { + #loadLink (location, targetLoc, target) { const path = resolve(this.path, location) const link = new Link({ installLinks: this.installLinks, diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js index 422819b2104b7e..4f8730cde7f382 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/rebuild.js @@ -9,11 +9,8 @@ const binLinks = require('bin-links') const runScript = require('@npmcli/run-script') const { callLimit: promiseCallLimit } = require('promise-call-limit') const { resolve } = require('path') -const { - isNodeGypPackage, - defaultGypInstallScript, -} = require('@npmcli/node-gyp') -const log = require('proc-log') +const { isNodeGypPackage, defaultGypInstallScript } = require('@npmcli/node-gyp') +const { log, time } = require('proc-log') const boolEnv = b => b ? '1' : '' const sortNodes = (a, b) => @@ -54,7 +51,7 @@ module.exports = cls => class Builder extends cls { // separates links nodes so that it can run // prepare scripts and link bins in the expected order - process.emit('time', 'build') + const timeEnd = time.start('build') const { depNodes, @@ -70,7 +67,7 @@ module.exports = cls => class Builder extends cls { await this.#build(linkNodes, { type: 'links' }) } - process.emit('timeEnd', 'build') + timeEnd() } // if we don't have a set of nodes, then just rebuild @@ -147,7 +144,7 @@ module.exports = cls => class Builder extends cls { } async #build (nodes, { type = 'deps' }) { - process.emit('time', `build:${type}`) + const timeEnd = time.start(`build:${type}`) await this.#buildQueues(nodes) @@ -168,11 +165,11 @@ module.exports = cls => class Builder extends cls { await this.#runScripts('postinstall') } - process.emit('timeEnd', `build:${type}`) + timeEnd() } async #buildQueues (nodes) { - process.emit('time', 'build:queue') + const timeEnd = time.start('build:queue') const set = new Set() const promises = [] @@ -210,7 +207,7 @@ module.exports = cls => class Builder extends cls { } } } - process.emit('timeEnd', 'build:queue') + timeEnd() } async [_checkBins] (node) { @@ -286,7 +283,7 @@ module.exports = cls => class Builder extends cls { return } - process.emit('time', `build:run:${event}`) + const timeEnd = time.start(`build:run:${event}`) const stdio = this.options.foregroundScripts ? 'inherit' : 'pipe' const limit = this.options.foregroundScripts ? 1 : undefined await promiseCallLimit(queue.map(node => async () => { @@ -309,8 +306,7 @@ module.exports = cls => class Builder extends cls { return } - const timer = `build:run:${event}:${location}` - process.emit('time', timer) + const timeEndLocation = time.start(`build:run:${event}:${location}`) log.info('run', pkg._id, event, location, pkg.scripts[event]) const env = { npm_package_resolved: resolved, @@ -356,9 +352,9 @@ module.exports = cls => class Builder extends cls { ? this[_handleOptionalFailure](node, p) : p) - process.emit('timeEnd', timer) + timeEndLocation() }), { limit }) - process.emit('timeEnd', `build:run:${event}`) + timeEnd() } async #linkAllBins () { @@ -367,7 +363,7 @@ module.exports = cls => class Builder extends cls { return } - process.emit('time', 'build:link') + const timeEnd = time.start('build:link') const promises = [] // sort the queue by node path, so that the module-local collision // detector in bin-links will always resolve the same way. @@ -377,7 +373,7 @@ module.exports = cls => class Builder extends cls { } await promiseAllRejectLate(promises) - process.emit('timeEnd', 'build:link') + timeEnd() } async #createBinLinks (node) { @@ -385,7 +381,7 @@ module.exports = cls => class Builder extends cls { return } - process.emit('time', `build:link:${node.location}`) + const timeEnd = time.start(`build:link:${node.location}`) const p = binLinks({ pkg: node.package, @@ -399,6 +395,6 @@ module.exports = cls => class Builder extends cls { ? this[_handleOptionalFailure](node, p) : p) - process.emit('timeEnd', `build:link:${node.location}`) + timeEnd() } } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js index a70e21821ecb86..96704f6556e0da 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js @@ -7,7 +7,7 @@ const npa = require('npm-package-arg') const semver = require('semver') const debug = require('../debug.js') const { walkUp } = require('walk-up-path') -const log = require('proc-log') +const { log, time } = require('proc-log') const hgi = require('hosted-git-info') const rpj = require('read-package-json-fast') @@ -38,119 +38,96 @@ const { saveTypeMap, hasSubKey } = require('../add-rm-pkg-deps.js') const Shrinkwrap = require('../shrinkwrap.js') const { defaultLockfileVersion } = Shrinkwrap -const _retiredPaths = Symbol('retiredPaths') -const _retiredUnchanged = Symbol('retiredUnchanged') -const _sparseTreeDirs = Symbol('sparseTreeDirs') -const _sparseTreeRoots = Symbol('sparseTreeRoots') -const _savePrefix = Symbol('savePrefix') +// Part of steps (steps need refactoring before we can do anything about these) const _retireShallowNodes = Symbol.for('retireShallowNodes') -const _getBundlesByDepth = Symbol('getBundlesByDepth') -const _registryResolved = Symbol('registryResolved') -const _addNodeToTrashList = Symbol.for('addNodeToTrashList') +const _loadBundlesAndUpdateTrees = Symbol.for('loadBundlesAndUpdateTrees') +const _submitQuickAudit = Symbol('submitQuickAudit') +const _addOmitsToTrashList = Symbol('addOmitsToTrashList') +const _unpackNewModules = Symbol.for('unpackNewModules') +const _build = Symbol.for('build') // shared by rebuild mixin const _trashList = Symbol.for('trashList') const _handleOptionalFailure = Symbol.for('handleOptionalFailure') const _loadTrees = Symbol.for('loadTrees') +// defined by rebuild mixin +const _checkBins = Symbol.for('checkBins') // shared symbols for swapping out when testing +// TODO tests should not be this deep into internals const _diffTrees = Symbol.for('diffTrees') const _createSparseTree = Symbol.for('createSparseTree') const _loadShrinkwrapsAndUpdateTrees = Symbol.for('loadShrinkwrapsAndUpdateTrees') -const _shrinkwrapInflated = Symbol('shrinkwrapInflated') -const _bundleUnpacked = Symbol('bundleUnpacked') -const _bundleMissing = Symbol('bundleMissing') const _reifyNode = Symbol.for('reifyNode') -const _extractOrLink = Symbol('extractOrLink') const _updateAll = Symbol.for('updateAll') const _updateNames = Symbol.for('updateNames') -// defined by rebuild mixin -const _checkBins = Symbol.for('checkBins') -const _symlink = Symbol('symlink') -const _warnDeprecated = Symbol('warnDeprecated') -const _loadBundlesAndUpdateTrees = Symbol.for('loadBundlesAndUpdateTrees') -const _submitQuickAudit = Symbol('submitQuickAudit') -const _unpackNewModules = Symbol.for('unpackNewModules') const _moveContents = Symbol.for('moveContents') const _moveBackRetiredUnchanged = Symbol.for('moveBackRetiredUnchanged') -const _build = Symbol.for('build') const _removeTrash = Symbol.for('removeTrash') const _renamePath = Symbol.for('renamePath') const _rollbackRetireShallowNodes = Symbol.for('rollbackRetireShallowNodes') const _rollbackCreateSparseTree = Symbol.for('rollbackCreateSparseTree') const _rollbackMoveBackRetiredUnchanged = Symbol.for('rollbackMoveBackRetiredUnchanged') const _saveIdealTree = Symbol.for('saveIdealTree') -const _copyIdealToActual = Symbol('copyIdealToActual') -const _addOmitsToTrashList = Symbol('addOmitsToTrashList') -const _packageLockOnly = Symbol('packageLockOnly') -const _dryRun = Symbol('dryRun') -const _validateNodeModules = Symbol('validateNodeModules') -const _nmValidated = Symbol('nmValidated') -const _validatePath = Symbol('validatePath') const _reifyPackages = Symbol.for('reifyPackages') -const _omitDev = Symbol('omitDev') -const _omitOptional = Symbol('omitOptional') -const _omitPeer = Symbol('omitPeer') - -const _pruneBundledMetadeps = Symbol('pruneBundledMetadeps') - -// defined by Ideal mixin +// defined by build-ideal-tree mixin const _resolvedAdd = Symbol.for('resolvedAdd') const _usePackageLock = Symbol.for('usePackageLock') -const _formatPackageLock = Symbol.for('formatPackageLock') +// used by build-ideal-tree mixin +const _addNodeToTrashList = Symbol.for('addNodeToTrashList') const _createIsolatedTree = Symbol.for('createIsolatedTree') module.exports = cls => class Reifier extends cls { + #bundleMissing = new Set() // child nodes we'd EXPECT to be included in a bundle, but aren't + #bundleUnpacked = new Set() // the nodes we unpack to read their bundles + #dryRun + #nmValidated = new Set() + #omitDev + #omitPeer + #omitOptional + #retiredPaths = {} + #retiredUnchanged = {} + #savePrefix + #shrinkwrapInflated = new Set() + #sparseTreeDirs = new Set() + #sparseTreeRoots = new Set() + constructor (options) { super(options) - const { - savePrefix = '^', - packageLockOnly = false, - dryRun = false, - formatPackageLock = true, - } = options - - this[_dryRun] = !!dryRun - this[_packageLockOnly] = !!packageLockOnly - this[_savePrefix] = savePrefix - this[_formatPackageLock] = !!formatPackageLock - - this.diff = null - this[_retiredPaths] = {} - this[_shrinkwrapInflated] = new Set() - this[_retiredUnchanged] = {} - this[_sparseTreeDirs] = new Set() - this[_sparseTreeRoots] = new Set() this[_trashList] = new Set() - // the nodes we unpack to read their bundles - this[_bundleUnpacked] = new Set() - // child nodes we'd EXPECT to be included in a bundle, but aren't - this[_bundleMissing] = new Set() - this[_nmValidated] = new Set() } // public method async reify (options = {}) { const linked = (options.installStrategy || this.options.installStrategy) === 'linked' - if (this[_packageLockOnly] && this.options.global) { + if (this.options.packageLockOnly && this.options.global) { const er = new Error('cannot generate lockfile for global packages') er.code = 'ESHRINKWRAPGLOBAL' throw er } const omit = new Set(options.omit || []) - this[_omitDev] = omit.has('dev') - this[_omitOptional] = omit.has('optional') - this[_omitPeer] = omit.has('peer') + this.#omitDev = omit.has('dev') + this.#omitOptional = omit.has('optional') + this.#omitPeer = omit.has('peer') // start tracker block this.addTracker('reify') - process.emit('time', 'reify') - await this[_validatePath]() + const timeEnd = time.start('reify') + // don't create missing dirs on dry runs + if (!this.options.packageLockOnly && !this.options.dryRun) { + // we do NOT want to set ownership on this folder, especially + // recursively, because it can have other side effects to do that + // in a project directory. We just want to make it if it's missing. + await mkdir(resolve(this.path), { recursive: true }) + + // do not allow the top-level node_modules to be a symlink + await this.#validateNodeModules(resolve(this.path, 'node_modules')) + } await this[_loadTrees](options) const oldTree = this.idealTree @@ -159,7 +136,7 @@ module.exports = cls => class Reifier extends cls { // this is currently technical debt which will be resolved in a refactor // of Node/Link trees log.warn('reify', 'The "linked" install strategy is EXPERIMENTAL and may contain bugs.') - this.idealTree = await this[_createIsolatedTree](this.idealTree) + this.idealTree = await this[_createIsolatedTree]() } await this[_diffTrees]() await this[_reifyPackages]() @@ -169,37 +146,139 @@ module.exports = cls => class Reifier extends cls { this.idealTree = oldTree } await this[_saveIdealTree](options) - await this[_copyIdealToActual]() - // This is a very bad pattern and I can't wait to stop doing it - this.auditReport = await this.auditReport + // clean up any trash that is still in the tree + for (const path of this[_trashList]) { + const loc = relpath(this.idealTree.realpath, path) + const node = this.idealTree.inventory.get(loc) + if (node && node.root === this.idealTree) { + node.parent = null + } + } - this.finishTracker('reify') - process.emit('timeEnd', 'reify') - return treeCheck(this.actualTree) - } + // if we filtered to only certain nodes, then anything ELSE needs + // to be untouched in the resulting actual tree, even if it differs + // in the idealTree. Copy over anything that was in the actual and + // was not changed, delete anything in the ideal and not actual. + // Then we move the entire idealTree over to this.actualTree, and + // save the hidden lockfile. + if (this.diff && this.diff.filterSet.size) { + const reroot = new Set() - async [_validatePath] () { - // don't create missing dirs on dry runs - if (this[_packageLockOnly] || this[_dryRun]) { - return + const { filterSet } = this.diff + const seen = new Set() + for (const [loc, ideal] of this.idealTree.inventory.entries()) { + seen.add(loc) + + // if it's an ideal node from the filter set, then skip it + // because we already made whatever changes were necessary + if (filterSet.has(ideal)) { + continue + } + + // otherwise, if it's not in the actualTree, then it's not a thing + // that we actually added. And if it IS in the actualTree, then + // it's something that we left untouched, so we need to record + // that. + const actual = this.actualTree.inventory.get(loc) + if (!actual) { + ideal.root = null + } else { + if ([...actual.linksIn].some(link => filterSet.has(link))) { + seen.add(actual.location) + continue + } + const { realpath, isLink } = actual + if (isLink && ideal.isLink && ideal.realpath === realpath) { + continue + } else { + reroot.add(actual) + } + } + } + + // now find any actual nodes that may not be present in the ideal + // tree, but were left behind by virtue of not being in the filter + for (const [loc, actual] of this.actualTree.inventory.entries()) { + if (seen.has(loc)) { + continue + } + seen.add(loc) + + // we know that this is something that ISN'T in the idealTree, + // or else we will have addressed it in the previous loop. + // If it's in the filterSet, that means we intentionally removed + // it, so nothing to do here. + if (filterSet.has(actual)) { + continue + } + + reroot.add(actual) + } + + // go through the rerooted actual nodes, and move them over. + for (const actual of reroot) { + actual.root = this.idealTree + } + + // prune out any tops that lack a linkIn, they are no longer relevant. + for (const top of this.idealTree.tops) { + if (top.linksIn.size === 0) { + top.root = null + } + } + + // need to calculate dep flags, since nodes may have been marked + // as extraneous or otherwise incorrect during transit. + calcDepFlags(this.idealTree) } - // we do NOT want to set ownership on this folder, especially - // recursively, because it can have other side effects to do that - // in a project directory. We just want to make it if it's missing. - await mkdir(resolve(this.path), { recursive: true }) + // save the ideal's meta as a hidden lockfile after we actualize it + this.idealTree.meta.filename = + this.idealTree.realpath + '/node_modules/.package-lock.json' + this.idealTree.meta.hiddenLockfile = true + this.idealTree.meta.lockfileVersion = defaultLockfileVersion + + this.actualTree = this.idealTree + this.idealTree = null + + if (!this.options.global) { + await this.actualTree.meta.save() + const ignoreScripts = !!this.options.ignoreScripts + // if we aren't doing a dry run or ignoring scripts and we actually made changes to the dep + // tree, then run the dependencies scripts + if (!this.options.dryRun && !ignoreScripts && this.diff && this.diff.children.length) { + const { path, package: pkg } = this.actualTree.target + const stdio = this.options.foregroundScripts ? 'inherit' : 'pipe' + const { scripts = {} } = pkg + for (const event of ['predependencies', 'dependencies', 'postdependencies']) { + if (Object.prototype.hasOwnProperty.call(scripts, event)) { + log.info('run', pkg._id, event, scripts[event]) + await time.start(`reify:run:${event}`, () => runScript({ + event, + path, + pkg, + stdio, + scriptShell: this.options.scriptShell, + })) + } + } + } + } + // This is a very bad pattern and I can't wait to stop doing it + this.auditReport = await this.auditReport - // do not allow the top-level node_modules to be a symlink - await this[_validateNodeModules](resolve(this.path, 'node_modules')) + this.finishTracker('reify') + timeEnd() + return treeCheck(this.actualTree) } async [_reifyPackages] () { // we don't submit the audit report or write to disk on dry runs - if (this[_dryRun]) { + if (this.options.dryRun) { return } - if (this[_packageLockOnly]) { + if (this.options.packageLockOnly) { // we already have the complete tree, so just audit it now, // and that's all we have to do here. return this[_submitQuickAudit]() @@ -248,6 +327,7 @@ module.exports = cls => class Reifier extends cls { throw reifyTerminated } } catch (er) { + // TODO rollbacks shouldn't be relied on to throw err await this[rollback](er) /* istanbul ignore next - rollback throws, should never hit this */ throw er @@ -269,16 +349,15 @@ module.exports = cls => class Reifier extends cls { // when doing a local install, we load everything and figure it all out. // when doing a global install, we *only* care about the explicit requests. [_loadTrees] (options) { - process.emit('time', 'reify:loadTrees') + const timeEnd = time.start('reify:loadTrees') const bitOpt = { ...options, - complete: this[_packageLockOnly] || this[_dryRun], + complete: this.options.packageLockOnly || this.options.dryRun, } // if we're only writing a package lock, then it doesn't matter what's here - if (this[_packageLockOnly]) { - return this.buildIdealTree(bitOpt) - .then(() => process.emit('timeEnd', 'reify:loadTrees')) + if (this.options.packageLockOnly) { + return this.buildIdealTree(bitOpt).then(timeEnd) } const actualOpt = this.options.global ? { @@ -312,7 +391,7 @@ module.exports = cls => class Reifier extends cls { return Promise.all([ this.loadActual(actualOpt), this.buildIdealTree(bitOpt), - ]).then(() => process.emit('timeEnd', 'reify:loadTrees')) + ]).then(timeEnd) } // the global install space tends to have a lot of stuff in it. don't @@ -322,15 +401,15 @@ module.exports = cls => class Reifier extends cls { // explicitRequests which is set during buildIdealTree return this.buildIdealTree(bitOpt) .then(() => this.loadActual(actualOpt)) - .then(() => process.emit('timeEnd', 'reify:loadTrees')) + .then(timeEnd) } [_diffTrees] () { - if (this[_packageLockOnly]) { + if (this.options.packageLockOnly) { return } - process.emit('time', 'reify:diffTrees') + const timeEnd = time.start('reify:diffTrees') // XXX if we have an existing diff already, there should be a way // to just invalidate the parts that changed, but avoid walking the // whole tree again. @@ -384,7 +463,7 @@ module.exports = cls => class Reifier extends cls { // find all the nodes that need to change between the actual // and ideal trees. this.diff = Diff.calculate({ - shrinkwrapInflated: this[_shrinkwrapInflated], + shrinkwrapInflated: this.#shrinkwrapInflated, filterNodes, actual: this.actualTree, ideal: this.idealTree, @@ -397,7 +476,7 @@ module.exports = cls => class Reifier extends cls { // because if we remove node_modules/FOO on case-insensitive systems, // it will remove the dep that we *want* at node_modules/foo. - process.emit('timeEnd', 'reify:diffTrees') + timeEnd() } // add the node and all its bins to the list of things to be @@ -406,7 +485,7 @@ module.exports = cls => class Reifier extends cls { // replace them when rolling back on failure. [_addNodeToTrashList] (node, retire = false) { const paths = [node.path, ...node.binPaths] - const moves = this[_retiredPaths] + const moves = this.#retiredPaths log.silly('reify', 'mark', retire ? 'retired' : 'deleted', paths) for (const path of paths) { if (retire) { @@ -422,8 +501,8 @@ module.exports = cls => class Reifier extends cls { // move aside the shallowest nodes in the tree that have to be // changed or removed, so that we can rollback if necessary. [_retireShallowNodes] () { - process.emit('time', 'reify:retireShallow') - const moves = this[_retiredPaths] = {} + const timeEnd = time.start('reify:retireShallow') + const moves = this.#retiredPaths = {} for (const diff of this.diff.children) { if (diff.action === 'CHANGE' || diff.action === 'REMOVE') { // we'll have to clean these up at the end, so add them to the list @@ -433,8 +512,7 @@ module.exports = cls => class Reifier extends cls { log.silly('reify', 'moves', moves) const movePromises = Object.entries(moves) .map(([from, to]) => this[_renamePath](from, to)) - return promiseAllRejectLate(movePromises) - .then(() => process.emit('timeEnd', 'reify:retireShallow')) + return promiseAllRejectLate(movePromises).then(timeEnd) } [_renamePath] (from, to, didMkdirp = false) { @@ -456,14 +534,14 @@ module.exports = cls => class Reifier extends cls { } [_rollbackRetireShallowNodes] (er) { - process.emit('time', 'reify:rollback:retireShallow') - const moves = this[_retiredPaths] + const timeEnd = time.start('reify:rollback:retireShallow') + const moves = this.#retiredPaths const movePromises = Object.entries(moves) .map(([from, to]) => this[_renamePath](to, from)) return promiseAllRejectLate(movePromises) // ignore subsequent rollback errors - .catch(er => {}) - .then(() => process.emit('timeEnd', 'reify:rollback:retireShallow')) + .catch(() => {}) + .then(timeEnd) .then(() => { throw er }) @@ -472,11 +550,11 @@ module.exports = cls => class Reifier extends cls { // adding to the trash list will skip reifying, and delete them // if they are currently in the tree and otherwise untouched. [_addOmitsToTrashList] () { - if (!this[_omitDev] && !this[_omitOptional] && !this[_omitPeer]) { + if (!this.#omitDev && !this.#omitOptional && !this.#omitPeer) { return } - process.emit('time', 'reify:trashOmits') + const timeEnd = time.start('reify:trashOmits') for (const node of this.idealTree.inventory.values()) { const { top } = node @@ -494,26 +572,26 @@ module.exports = cls => class Reifier extends cls { // omit node if the dep type matches any omit flags that were set if ( - node.peer && this[_omitPeer] || - node.dev && this[_omitDev] || - node.optional && this[_omitOptional] || - node.devOptional && this[_omitOptional] && this[_omitDev] + node.peer && this.#omitPeer || + node.dev && this.#omitDev || + node.optional && this.#omitOptional || + node.devOptional && this.#omitOptional && this.#omitDev ) { this[_addNodeToTrashList](node) } } - process.emit('timeEnd', 'reify:trashOmits') + timeEnd() } [_createSparseTree] () { - process.emit('time', 'reify:createSparse') + const timeEnd = time.start('reify:createSparse') // if we call this fn again, we look for the previous list // so that we can avoid making the same directory multiple times const leaves = this.diff.leaves .filter(diff => { return (diff.action === 'ADD' || diff.action === 'CHANGE') && - !this[_sparseTreeDirs].has(diff.ideal.path) && + !this.#sparseTreeDirs.has(diff.ideal.path) && !diff.ideal.isLink }) .map(diff => diff.ideal) @@ -530,37 +608,36 @@ module.exports = cls => class Reifier extends cls { continue } dirsChecked.add(d) - const st = await lstat(d).catch(er => null) + const st = await lstat(d).catch(() => null) // this can happen if we have a link to a package with a name // that the filesystem treats as if it is the same thing. // would be nice to have conditional istanbul ignores here... /* istanbul ignore next - defense in depth */ if (st && !st.isDirectory()) { const retired = retirePath(d) - this[_retiredPaths][d] = retired + this.#retiredPaths[d] = retired this[_trashList].add(retired) await this[_renamePath](d, retired) } } - this[_sparseTreeDirs].add(node.path) + this.#sparseTreeDirs.add(node.path) const made = await mkdir(node.path, { recursive: true }) // if the directory already exists, made will be undefined. if that's the case // we don't want to remove it because we aren't the ones who created it so we - // omit it from the _sparseTreeRoots + // omit it from the #sparseTreeRoots if (made) { - this[_sparseTreeRoots].add(made) + this.#sparseTreeRoots.add(made) } - })) - .then(() => process.emit('timeEnd', 'reify:createSparse')) + })).then(timeEnd) } [_rollbackCreateSparseTree] (er) { - process.emit('time', 'reify:rollback:createSparse') + const timeEnd = time.start('reify:rollback:createSparse') // cut the roots of the sparse tree that were created, not the leaves - const roots = this[_sparseTreeRoots] + const roots = this.#sparseTreeRoots // also delete the moves that we retired, so that we can move them back const failures = [] - const targets = [...roots, ...Object.keys(this[_retiredPaths])] + const targets = [...roots, ...Object.keys(this.#retiredPaths)] const unlinks = targets .map(path => rm(path, { recursive: true, force: true }).catch(er => failures.push([path, er]))) return promiseAllRejectLate(unlinks).then(() => { @@ -569,7 +646,7 @@ module.exports = cls => class Reifier extends cls { log.warn('cleanup', 'Failed to remove some directories', failures) } }) - .then(() => process.emit('timeEnd', 'reify:rollback:createSparse')) + .then(timeEnd) .then(() => this[_rollbackRetireShallowNodes](er)) } @@ -577,7 +654,7 @@ module.exports = cls => class Reifier extends cls { // we need to unpack them, read that shrinkwrap file, and then update // the tree by calling loadVirtual with the node as the root. [_loadShrinkwrapsAndUpdateTrees] () { - const seen = this[_shrinkwrapInflated] + const seen = this.#shrinkwrapInflated const shrinkwraps = this.diff.leaves .filter(d => (d.action === 'CHANGE' || d.action === 'ADD' || !d.action) && d.ideal.hasShrinkwrap && !seen.has(d.ideal) && @@ -587,7 +664,7 @@ module.exports = cls => class Reifier extends cls { return } - process.emit('time', 'reify:loadShrinkwraps') + const timeEnd = time.start('reify:loadShrinkwraps') const Arborist = this.constructor return promiseAllRejectLate(shrinkwraps.map(diff => { @@ -604,7 +681,7 @@ module.exports = cls => class Reifier extends cls { .then(() => this[_createSparseTree]()) .then(() => this[_addOmitsToTrashList]()) .then(() => this[_loadShrinkwrapsAndUpdateTrees]()) - .then(() => process.emit('timeEnd', 'reify:loadShrinkwraps')) + .then(timeEnd) } // create a symlink for Links, extract for Nodes @@ -619,8 +696,7 @@ module.exports = cls => class Reifier extends cls { return node } - const timer = `reifyNode:${node.location}` - process.emit('time', timer) + const timeEnd = time.start(`reifyNode:${node.location}`) this.addTracker('reify', node.name, node.location) const { npmVersion, nodeVersion, cpu, os, libc } = this.options @@ -636,35 +712,40 @@ module.exports = cls => class Reifier extends cls { checkPlatform(node.package, false, { cpu, os, libc }) } await this[_checkBins](node) - await this[_extractOrLink](node) - await this[_warnDeprecated](node) + await this.#extractOrLink(node) + const { _id, deprecated } = node.package + // The .catch is in _handleOptionalFailure. Not ideal, this should be cleaned up. + // eslint-disable-next-line promise/always-return + if (deprecated) { + log.warn('deprecated', `${_id}: ${deprecated}`) + } }) return this[_handleOptionalFailure](node, p) .then(() => { this.finishTracker('reify', node.name, node.location) - process.emit('timeEnd', timer) + timeEnd() return node }) } // do not allow node_modules to be a symlink - async [_validateNodeModules] (nm) { - if (this.options.force || this[_nmValidated].has(nm)) { + async #validateNodeModules (nm) { + if (this.options.force || this.#nmValidated.has(nm)) { return } const st = await lstat(nm).catch(() => null) if (!st || st.isDirectory()) { - this[_nmValidated].add(nm) + this.#nmValidated.add(nm) return } log.warn('reify', 'Removing non-directory', nm) await rm(nm, { recursive: true, force: true }) } - async [_extractOrLink] (node) { + async #extractOrLink (node) { const nm = resolve(node.parent.path, 'node_modules') - await this[_validateNodeModules](nm) + await this.#validateNodeModules(nm) if (!node.isLink) { // in normal cases, node.resolved should *always* be set by now. @@ -676,7 +757,7 @@ module.exports = cls => class Reifier extends cls { // entirely, since we can't possibly reify it. let res = null if (node.resolved) { - const registryResolved = this[_registryResolved](node.resolved) + const registryResolved = this.#registryResolved(node.resolved) if (registryResolved) { res = `${node.name}@${registryResolved}` } @@ -698,7 +779,7 @@ module.exports = cls => class Reifier extends cls { return } await debug(async () => { - const st = await lstat(node.path).catch(e => null) + const st = await lstat(node.path).catch(() => null) if (st && !st.isDirectory()) { debug.log('unpacking into a non-directory', node) throw Object.assign(new Error('ENOTDIR: not a directory'), { @@ -722,10 +803,8 @@ module.exports = cls => class Reifier extends cls { // node.isLink await rm(node.path, { recursive: true, force: true }) - await this[_symlink](node) - } - async [_symlink] (node) { + // symlink const dir = dirname(node.path) const target = node.realpath const rel = relative(dir, target) @@ -733,17 +812,10 @@ module.exports = cls => class Reifier extends cls { return symlink(rel, node.path, 'junction') } - [_warnDeprecated] (node) { - const { _id, deprecated } = node.package - if (deprecated) { - log.warn('deprecated', `${_id}: ${deprecated}`) - } - } - // if the node is optional, then the failure of the promise is nonfatal // just add it and its optional set to the trash list. [_handleOptionalFailure] (node, p) { - return (node.optional ? p.catch(er => { + return (node.optional ? p.catch(() => { const set = optionalSet(node) for (node of set) { log.verbose('reify', 'failed optional dependency', node.path) @@ -752,7 +824,7 @@ module.exports = cls => class Reifier extends cls { }) : p).then(() => node) } - [_registryResolved] (resolved) { + #registryResolved (resolved) { // the default registry url is a magic value meaning "the currently // configured registry". // `resolved` must never be falsey. @@ -782,21 +854,51 @@ module.exports = cls => class Reifier extends cls { // by the contents of the package. however, in their case, rather than // shipping a virtual tree that must be reified, they ship an entire // reified actual tree that must be unpacked and not modified. - [_loadBundlesAndUpdateTrees] ( - depth = 0, bundlesByDepth = this[_getBundlesByDepth]() - ) { + [_loadBundlesAndUpdateTrees] (depth = 0, bundlesByDepth) { + let maxBundleDepth + if (!bundlesByDepth) { + bundlesByDepth = new Map() + maxBundleDepth = -1 + dfwalk({ + tree: this.diff, + visit: diff => { + const node = diff.ideal + if (!node) { + return + } + if (node.isProjectRoot) { + return + } + + const { bundleDependencies } = node.package + if (bundleDependencies && bundleDependencies.length) { + maxBundleDepth = Math.max(maxBundleDepth, node.depth) + if (!bundlesByDepth.has(node.depth)) { + bundlesByDepth.set(node.depth, [node]) + } else { + bundlesByDepth.get(node.depth).push(node) + } + } + }, + getChildren: diff => diff.children, + }) + + bundlesByDepth.set('maxBundleDepth', maxBundleDepth) + } else { + maxBundleDepth = bundlesByDepth.get('maxBundleDepth') + } + if (depth === 0) { - process.emit('time', 'reify:loadBundles') + time.start('reify:loadBundles') } - const maxBundleDepth = bundlesByDepth.get('maxBundleDepth') if (depth > maxBundleDepth) { // if we did something, then prune the tree and update the diffs if (maxBundleDepth !== -1) { - this[_pruneBundledMetadeps](bundlesByDepth) + this.#pruneBundledMetadeps(bundlesByDepth) this[_diffTrees]() } - process.emit('timeEnd', 'reify:loadBundles') + time.end('reify:loadBundles') return } @@ -814,7 +916,7 @@ module.exports = cls => class Reifier extends cls { // extract all the nodes with bundles return promiseCallLimit(set.map(node => { return () => { - this[_bundleUnpacked].add(node) + this.#bundleUnpacked.add(node) return this[_reifyNode](node) } }), { rejectLate: true }) @@ -843,46 +945,15 @@ module.exports = cls => class Reifier extends cls { }, }) for (const name of notTransplanted) { - this[_bundleMissing].add(node.children.get(name)) + this.#bundleMissing.add(node.children.get(name)) } }))) // move onto the next level of bundled items .then(() => this[_loadBundlesAndUpdateTrees](depth + 1, bundlesByDepth)) } - [_getBundlesByDepth] () { - const bundlesByDepth = new Map() - let maxBundleDepth = -1 - dfwalk({ - tree: this.diff, - visit: diff => { - const node = diff.ideal - if (!node) { - return - } - if (node.isProjectRoot) { - return - } - - const { bundleDependencies } = node.package - if (bundleDependencies && bundleDependencies.length) { - maxBundleDepth = Math.max(maxBundleDepth, node.depth) - if (!bundlesByDepth.has(node.depth)) { - bundlesByDepth.set(node.depth, [node]) - } else { - bundlesByDepth.get(node.depth).push(node) - } - } - }, - getChildren: diff => diff.children, - }) - - bundlesByDepth.set('maxBundleDepth', maxBundleDepth) - return bundlesByDepth - } - // https://github.com/npm/cli/issues/1597#issuecomment-667639545 - [_pruneBundledMetadeps] (bundlesByDepth) { + #pruneBundledMetadeps (bundlesByDepth) { const bundleShadowed = new Set() // Example dep graph: @@ -981,7 +1052,7 @@ module.exports = cls => class Reifier extends cls { // before finishing the reify() and returning the tree. Thus, we do // NOT return the promise, as the intent is for this to run in parallel // with the reification, and be resolved at a later time. - process.emit('time', 'reify:audit') + const timeEnd = time.start('reify:audit') const options = { ...this.options } const tree = this.idealTree @@ -995,7 +1066,7 @@ module.exports = cls => class Reifier extends cls { } this.auditReport = AuditReport.load(tree, options).then(res => { - process.emit('timeEnd', 'reify:audit') + timeEnd() return res }) } @@ -1005,7 +1076,7 @@ module.exports = cls => class Reifier extends cls { // kicking off each unpack job. If any fail, we rm the sparse // tree entirely and try to put everything back where it was. [_unpackNewModules] () { - process.emit('time', 'reify:unpack') + const timeEnd = time.start('reify:unpack') const unpacks = [] dfwalk({ tree: this.diff, @@ -1016,9 +1087,9 @@ module.exports = cls => class Reifier extends cls { } const node = diff.ideal - const bd = this[_bundleUnpacked].has(node) - const sw = this[_shrinkwrapInflated].has(node) - const bundleMissing = this[_bundleMissing].has(node) + const bd = this.#bundleUnpacked.has(node) + const sw = this.#shrinkwrapInflated.has(node) + const bundleMissing = this.#bundleMissing.has(node) // check whether we still need to unpack this one. // test the inDepBundle last, since that's potentially a tree walk. @@ -1038,8 +1109,7 @@ module.exports = cls => class Reifier extends cls { }, getChildren: diff => diff.children, }) - return promiseAllRejectLate(unpacks) - .then(() => process.emit('timeEnd', 'reify:unpack')) + return promiseAllRejectLate(unpacks).then(timeEnd) } // This is the part where we move back the unchanging nodes that were @@ -1054,9 +1124,9 @@ module.exports = cls => class Reifier extends cls { // This is sort of an inverse diff tree, of all the nodes where // the actualTree and idealTree _don't_ differ, starting from the // shallowest nodes that we moved aside in the first place. - process.emit('time', 'reify:unretire') - const moves = this[_retiredPaths] - this[_retiredUnchanged] = {} + const timeEnd = time.start('reify:unretire') + const moves = this.#retiredPaths + this.#retiredUnchanged = {} return promiseAllRejectLate(this.diff.children.map(diff => { // skip if nothing was retired if (diff.action !== 'CHANGE' && diff.action !== 'REMOVE') { @@ -1079,7 +1149,7 @@ module.exports = cls => class Reifier extends cls { } }) - this[_retiredUnchanged][retireFolder] = [] + this.#retiredUnchanged[retireFolder] = [] return promiseAllRejectLate(diff.unchanged.map(node => { // no need to roll back links, since we'll just delete them anyway if (node.isLink) { @@ -1088,11 +1158,11 @@ module.exports = cls => class Reifier extends cls { } // will have been moved/unpacked along with bundler - if (node.inDepBundle && !this[_bundleMissing].has(node)) { + if (node.inDepBundle && !this.#bundleMissing.has(node)) { return } - this[_retiredUnchanged][retireFolder].push(node) + this.#retiredUnchanged[retireFolder].push(node) const rel = relative(realFolder, node.path) const fromPath = resolve(retireFolder, rel) @@ -1102,8 +1172,7 @@ module.exports = cls => class Reifier extends cls { const dir = bd && bd.length ? node.path + '/node_modules' : node.path return mkdir(dir, { recursive: true }).then(() => this[_moveContents](node, fromPath)) })) - })) - .then(() => process.emit('timeEnd', 'reify:unretire')) + })).then(timeEnd) } // move the contents from the fromPath to the node.path @@ -1120,10 +1189,10 @@ module.exports = cls => class Reifier extends cls { } [_rollbackMoveBackRetiredUnchanged] (er) { - const moves = this[_retiredPaths] + const moves = this.#retiredPaths // flip the mapping around to go back const realFolders = new Map(Object.entries(moves).map(([k, v]) => [v, k])) - const promises = Object.entries(this[_retiredUnchanged]) + const promises = Object.entries(this.#retiredUnchanged) .map(([retireFolder, nodes]) => promiseAllRejectLate(nodes.map(node => { const realFolder = realFolders.get(retireFolder) const rel = relative(realFolder, node.path) @@ -1135,7 +1204,7 @@ module.exports = cls => class Reifier extends cls { } [_build] () { - process.emit('time', 'reify:build') + const timeEnd = time.start('reify:build') // for all the things being installed, run their appropriate scripts // run in tip->root order, so as to be more likely to build a node's @@ -1167,8 +1236,7 @@ module.exports = cls => class Reifier extends cls { } } - return this.rebuild({ nodes, handleOptionalFailure: true }) - .then(() => process.emit('timeEnd', 'reify:build')) + return this.rebuild({ nodes, handleOptionalFailure: true }).then(timeEnd) } // the tree is pretty much built now, so it's cleanup time. @@ -1176,7 +1244,7 @@ module.exports = cls => class Reifier extends cls { // If this fails, there isn't much we can do but tell the user about it. // Thankfully, it's pretty unlikely that it'll fail, since rm is a node builtin. async [_removeTrash] () { - process.emit('time', 'reify:trash') + const timeEnd = time.start('reify:trash') const promises = [] const failures = [] const _rm = path => rm(path, { recursive: true, force: true }).catch(er => failures.push([path, er])) @@ -1189,7 +1257,8 @@ module.exports = cls => class Reifier extends cls { if (failures.length) { log.warn('cleanup', 'Failed to remove some directories', failures) } - process.emit('timeEnd', 'reify:trash') + + timeEnd() } // last but not least, we save the ideal tree metadata to the package-lock @@ -1215,14 +1284,14 @@ module.exports = cls => class Reifier extends cls { const saveIdealTree = !( (!save && !hasUpdates) || this.options.global - || this[_dryRun] + || this.options.dryRun ) if (!saveIdealTree) { return false } - process.emit('time', 'reify:save') + const timeEnd = time.start('reify:save') const updatedTrees = new Set() const updateNodes = nodes => { @@ -1251,7 +1320,7 @@ module.exports = cls => class Reifier extends cls { const isLocalDep = req.type === 'directory' || req.type === 'file' if (req.registry) { const version = child.version - const prefixRange = version ? this[_savePrefix] + version : '*' + const prefixRange = version ? this.options.savePrefix + version : '*' // if we installed a range, then we save the range specified // if it is not a subset of the ^x.y.z. eg, installing a range // of `1.x <1.2.3` will not be saved as `^1.2.0`, because that @@ -1286,7 +1355,7 @@ module.exports = cls => class Reifier extends cls { // using their relative path if (edge.type === 'workspace') { const { version } = edge.to.target - const prefixRange = version ? this[_savePrefix] + version : '*' + const prefixRange = version ? this.options.savePrefix + version : '*' newSpec = prefixRange } else { // save the relative path in package.json @@ -1455,154 +1524,12 @@ module.exports = cls => class Reifier extends cls { // TODO this ignores options.save await this.idealTree.meta.save({ - format: (this[_formatPackageLock] && format) ? format - : this[_formatPackageLock], + format: (this.options.formatPackageLock && format) ? format + : this.options.formatPackageLock, }) } - process.emit('timeEnd', 'reify:save') + timeEnd() return true } - - async [_copyIdealToActual] () { - // clean up any trash that is still in the tree - for (const path of this[_trashList]) { - const loc = relpath(this.idealTree.realpath, path) - const node = this.idealTree.inventory.get(loc) - if (node && node.root === this.idealTree) { - node.parent = null - } - } - - // if we filtered to only certain nodes, then anything ELSE needs - // to be untouched in the resulting actual tree, even if it differs - // in the idealTree. Copy over anything that was in the actual and - // was not changed, delete anything in the ideal and not actual. - // Then we move the entire idealTree over to this.actualTree, and - // save the hidden lockfile. - if (this.diff && this.diff.filterSet.size) { - const reroot = new Set() - - const { filterSet } = this.diff - const seen = new Set() - for (const [loc, ideal] of this.idealTree.inventory.entries()) { - seen.add(loc) - - // if it's an ideal node from the filter set, then skip it - // because we already made whatever changes were necessary - if (filterSet.has(ideal)) { - continue - } - - // otherwise, if it's not in the actualTree, then it's not a thing - // that we actually added. And if it IS in the actualTree, then - // it's something that we left untouched, so we need to record - // that. - const actual = this.actualTree.inventory.get(loc) - if (!actual) { - ideal.root = null - } else { - if ([...actual.linksIn].some(link => filterSet.has(link))) { - seen.add(actual.location) - continue - } - const { realpath, isLink } = actual - if (isLink && ideal.isLink && ideal.realpath === realpath) { - continue - } else { - reroot.add(actual) - } - } - } - - // now find any actual nodes that may not be present in the ideal - // tree, but were left behind by virtue of not being in the filter - for (const [loc, actual] of this.actualTree.inventory.entries()) { - if (seen.has(loc)) { - continue - } - seen.add(loc) - - // we know that this is something that ISN'T in the idealTree, - // or else we will have addressed it in the previous loop. - // If it's in the filterSet, that means we intentionally removed - // it, so nothing to do here. - if (filterSet.has(actual)) { - continue - } - - reroot.add(actual) - } - - // go through the rerooted actual nodes, and move them over. - for (const actual of reroot) { - actual.root = this.idealTree - } - - // prune out any tops that lack a linkIn, they are no longer relevant. - for (const top of this.idealTree.tops) { - if (top.linksIn.size === 0) { - top.root = null - } - } - - // need to calculate dep flags, since nodes may have been marked - // as extraneous or otherwise incorrect during transit. - calcDepFlags(this.idealTree) - } - - // save the ideal's meta as a hidden lockfile after we actualize it - this.idealTree.meta.filename = - this.idealTree.realpath + '/node_modules/.package-lock.json' - this.idealTree.meta.hiddenLockfile = true - this.idealTree.meta.lockfileVersion = defaultLockfileVersion - - this.actualTree = this.idealTree - this.idealTree = null - - if (!this.options.global) { - await this.actualTree.meta.save() - const ignoreScripts = !!this.options.ignoreScripts - // if we aren't doing a dry run or ignoring scripts and we actually made changes to the dep - // tree, then run the dependencies scripts - if (!this[_dryRun] && !ignoreScripts && this.diff && this.diff.children.length) { - const { path, package: pkg } = this.actualTree.target - const stdio = this.options.foregroundScripts ? 'inherit' : 'pipe' - const { scripts = {} } = pkg - for (const event of ['predependencies', 'dependencies', 'postdependencies']) { - if (Object.prototype.hasOwnProperty.call(scripts, event)) { - const timer = `reify:run:${event}` - process.emit('time', timer) - log.info('run', pkg._id, event, scripts[event]) - await runScript({ - event, - path, - pkg, - stdio, - scriptShell: this.options.scriptShell, - }) - process.emit('timeEnd', timer) - } - } - } - } - } - - async dedupe (options = {}) { - // allow the user to set options on the ctor as well. - // XXX: deprecate separate method options objects. - options = { ...this.options, ...options } - const tree = await this.loadVirtual().catch(() => this.loadActual()) - const names = [] - for (const name of tree.inventory.query('name')) { - if (tree.inventory.query('name', name).size > 1) { - names.push(name) - } - } - return this.reify({ - ...options, - preferDedupe: true, - update: { names }, - }) - } } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/audit-report.js b/deps/npm/node_modules/@npmcli/arborist/lib/audit-report.js index 387919f610829e..f7700ce9119de3 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/audit-report.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/audit-report.js @@ -13,7 +13,7 @@ const _fixAvailable = Symbol('fixAvailable') const _checkTopNode = Symbol('checkTopNode') const _init = Symbol('init') const _omit = Symbol('omit') -const log = require('proc-log') +const { log, time } = require('proc-log') const fetch = require('npm-registry-fetch') @@ -117,7 +117,7 @@ class AuditReport extends Map { } async [_init] () { - process.emit('time', 'auditReport:init') + const timeEnd = time.start('auditReport:init') const promises = [] for (const [name, advisories] of Object.entries(this.report)) { @@ -210,7 +210,8 @@ class AuditReport extends Map { } } } - process.emit('timeEnd', 'auditReport:init') + + timeEnd() } [_checkTopNode] (topNode, vuln, spec) { @@ -306,7 +307,7 @@ class AuditReport extends Map { return null } - process.emit('time', 'auditReport:getReport') + const timeEnd = time.start('auditReport:getReport') try { try { // first try the super fast bulk advisory listing @@ -347,7 +348,7 @@ class AuditReport extends Map { this.error = er return null } finally { - process.emit('timeEnd', 'auditReport:getReport') + timeEnd() } } } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/dep-valid.js b/deps/npm/node_modules/@npmcli/arborist/lib/dep-valid.js index 4afb5e47cf111f..58656e8dbbad29 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/dep-valid.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/dep-valid.js @@ -124,7 +124,7 @@ const linkValid = (child, requested, requestor) => { return isLink && relative(child.realpath, requested.fetchSpec) === '' } -const tarballValid = (child, requested, requestor) => { +const tarballValid = (child, requested) => { if (child.isLink) { return false } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/inventory.js b/deps/npm/node_modules/@npmcli/arborist/lib/inventory.js index 0885034666b50a..7b3f294fdab2c3 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/inventory.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/inventory.js @@ -130,7 +130,7 @@ class Inventory extends Map { return super.get(node.location) === node } - set (k, v) { + set () { throw new Error('direct set() not supported, use inventory.add(node)') } } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/place-dep.js b/deps/npm/node_modules/@npmcli/arborist/lib/place-dep.js index bf0fef6525343a..fca36eb6856137 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/place-dep.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/place-dep.js @@ -8,7 +8,7 @@ // a result. const localeCompare = require('@isaacs/string-locale-compare')('en') -const log = require('proc-log') +const { log } = require('proc-log') const { redact } = require('@npmcli/redact') const deepestNestingTarget = require('./deepest-nesting-target.js') const CanPlaceDep = require('./can-place-dep.js') diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/query-selector-all.js b/deps/npm/node_modules/@npmcli/arborist/lib/query-selector-all.js index c8ec866f0f9691..77640a3803d13b 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/query-selector-all.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/query-selector-all.js @@ -3,7 +3,7 @@ const { resolve } = require('path') const { parser, arrayDelimiter } = require('@npmcli/query') const localeCompare = require('@isaacs/string-locale-compare')('en') -const log = require('proc-log') +const { log } = require('proc-log') const { minimatch } = require('minimatch') const npa = require('npm-package-arg') const pacote = require('pacote') @@ -650,27 +650,27 @@ class Results { // operators for attribute selectors const attributeOperators = { // attribute value is equivalent - '=' ({ attr, value, insensitive }) { + '=' ({ attr, value }) { return attr === value }, // attribute value contains word - '~=' ({ attr, value, insensitive }) { + '~=' ({ attr, value }) { return (attr.match(/\w+/g) || []).includes(value) }, // attribute value contains string - '*=' ({ attr, value, insensitive }) { + '*=' ({ attr, value }) { return attr.includes(value) }, // attribute value is equal or starts with - '|=' ({ attr, value, insensitive }) { + '|=' ({ attr, value }) { return attr.startsWith(`${value}-`) }, // attribute value starts with - '^=' ({ attr, value, insensitive }) { + '^=' ({ attr, value }) { return attr.startsWith(value) }, // attribute value ends with - '$=' ({ attr, value, insensitive }) { + '$=' ({ attr, value }) { return attr.endsWith(value) }, } diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/shrinkwrap.js b/deps/npm/node_modules/@npmcli/arborist/lib/shrinkwrap.js index e6525ffe67b65d..026abc55ccba18 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/shrinkwrap.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/shrinkwrap.js @@ -33,7 +33,7 @@ const mismatch = (a, b) => a && b && a !== b // After calling this.commit(), any nodes not present in the tree will have // been removed from the shrinkwrap data as well. -const log = require('proc-log') +const { log } = require('proc-log') const YarnLock = require('./yarn-lock.js') const { readFile, @@ -1145,6 +1145,7 @@ class Shrinkwrap { throw new Error('run load() before saving data') } + // This must be called before the lockfile conversion check below since it sets properties as part of `commit()` const json = this.toString(options) if ( !this.hiddenLockfile @@ -1155,6 +1156,7 @@ class Shrinkwrap { `Converting lock file (${relative(process.cwd(), this.filename)}) from v${this.originalLockfileVersion} -> v${this.lockfileVersion}` ) } + return Promise.all([ writeFile(this.filename, json).catch(er => { if (this.hiddenLockfile) { diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/tracker.js b/deps/npm/node_modules/@npmcli/arborist/lib/tracker.js index 5acb32a5a7cfd9..4a754d995dfcd2 100644 --- a/deps/npm/node_modules/@npmcli/arborist/lib/tracker.js +++ b/deps/npm/node_modules/@npmcli/arborist/lib/tracker.js @@ -1,12 +1,12 @@ -const npmlog = require('npmlog') +const proggy = require('proggy') module.exports = cls => class Tracker extends cls { #progress = new Map() - #setProgress - constructor (options = {}) { - super(options) - this.#setProgress = !!options.progress + #createTracker (key, name) { + const tracker = new proggy.Tracker(name ?? key) + tracker.on('done', () => this.#progress.delete(key)) + this.#progress.set(key, tracker) } addTracker (section, subsection = null, key = null) { @@ -26,22 +26,17 @@ module.exports = cls => class Tracker extends cls { this.#onError(`Tracker "${section}" already exists`) } else if (!hasTracker && subsection === null) { // 1. no existing tracker, no subsection - // Create a new tracker from npmlog - // starts progress bar - if (this.#setProgress && this.#progress.size === 0) { - npmlog.enableProgress() - } - - this.#progress.set(section, npmlog.newGroup(section)) + // Create a new progress tracker + this.#createTracker(section) } else if (!hasTracker && subsection !== null) { // 2. no parent tracker and subsection this.#onError(`Parent tracker "${section}" does not exist`) } else if (!hasTracker || !hasSubtracker) { // 3. existing parent tracker, no subsection tracker - // Create a new subtracker in this.#progress from parent tracker - this.#progress.set(`${section}:${key}`, - this.#progress.get(section).newGroup(`${section}:${subsection}`) - ) + // Create a new subtracker and update parents + const parentTracker = this.#progress.get(section) + parentTracker.update(parentTracker.value, parentTracker.total + 1) + this.#createTracker(`${section}:${key}`, `${section}:${subsection}`) } // 4. existing parent tracker, existing subsection tracker // skip it @@ -70,32 +65,22 @@ module.exports = cls => class Tracker extends cls { this.finishTracker(section, key) } } - // remove parent tracker this.#progress.get(section).finish() - this.#progress.delete(section) - - // remove progress bar if all - // trackers are finished - if (this.#setProgress && this.#progress.size === 0) { - npmlog.disableProgress() - } } else if (!hasTracker && subsection === null) { // 1. no existing parent tracker, no subsection this.#onError(`Tracker "${section}" does not exist`) } else if (!hasTracker || hasSubtracker) { // 2. subtracker exists // Finish subtracker and remove from this.#progress + const parentTracker = this.#progress.get(section) + parentTracker.update(parentTracker.value + 1) this.#progress.get(`${section}:${key}`).finish() - this.#progress.delete(`${section}:${key}`) } // 3. existing parent tracker, no subsection } #onError (msg) { - if (this.#setProgress) { - npmlog.disableProgress() - } throw new Error(msg) } } diff --git a/deps/npm/node_modules/@npmcli/arborist/package.json b/deps/npm/node_modules/@npmcli/arborist/package.json index 3a92e669d4bb68..11c0ab4df3b529 100644 --- a/deps/npm/node_modules/@npmcli/arborist/package.json +++ b/deps/npm/node_modules/@npmcli/arborist/package.json @@ -1,19 +1,19 @@ { "name": "@npmcli/arborist", - "version": "7.4.2", + "version": "7.5.1", "description": "Manage node_modules trees", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/fs": "^3.1.0", - "@npmcli/installed-package-contents": "^2.0.2", + "@npmcli/installed-package-contents": "^2.1.0", "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.0.0", + "@npmcli/metavuln-calculator": "^7.1.0", "@npmcli/name-from-folder": "^2.0.0", "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", + "@npmcli/package-json": "^5.1.0", "@npmcli/query": "^3.1.0", - "@npmcli/redact": "^1.1.0", - "@npmcli/run-script": "^7.0.2", + "@npmcli/redact": "^2.0.0", + "@npmcli/run-script": "^8.1.0", "bin-links": "^4.0.1", "cacache": "^18.0.0", "common-ancestor-path": "^1.0.1", @@ -23,13 +23,13 @@ "minimatch": "^9.0.4", "nopt": "^7.0.0", "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.1", + "npm-package-arg": "^11.0.2", "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.2.0", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", + "npm-registry-fetch": "^17.0.0", + "pacote": "^18.0.1", "parse-conflict-json": "^3.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.2.0", + "proggy": "^2.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", "read-package-json-fast": "^3.0.2", @@ -62,7 +62,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/arborist" }, "author": "GitHub Inc.", diff --git a/deps/npm/node_modules/@npmcli/config/lib/definitions/definitions.js b/deps/npm/node_modules/@npmcli/config/lib/definitions/definitions.js index 3565cdb4feb44b..57ab1716118386 100644 --- a/deps/npm/node_modules/@npmcli/config/lib/definitions/definitions.js +++ b/deps/npm/node_modules/@npmcli/config/lib/definitions/definitions.js @@ -7,10 +7,10 @@ const { join } = require('node:path') const isWindows = process.platform === 'win32' // used by cafile flattening to flatOptions.ca -const fs = require('fs') +const { readFileSync } = require('fs') const maybeReadFile = file => { try { - return fs.readFileSync(file, 'utf8') + return readFileSync(file, 'utf8') } catch (er) { if (er.code !== 'ENOENT') { throw er diff --git a/deps/npm/node_modules/@npmcli/config/lib/index.js b/deps/npm/node_modules/@npmcli/config/lib/index.js index 1ff19c128696ca..c99292db9afb40 100644 --- a/deps/npm/node_modules/@npmcli/config/lib/index.js +++ b/deps/npm/node_modules/@npmcli/config/lib/index.js @@ -2,7 +2,7 @@ const { walkUp } = require('walk-up-path') const ini = require('ini') const nopt = require('nopt') -const log = require('proc-log') +const { log, time } = require('proc-log') const { resolve, dirname, join } = require('node:path') const { homedir } = require('node:os') @@ -201,7 +201,7 @@ class Config { } // create the object for flat options passed to deps - process.emit('time', 'config:load:flatten') + const timeEnd = time.start('config:load:flatten') this.#flatOptions = {} // walk from least priority to highest for (const { data } of this.data.values()) { @@ -209,7 +209,7 @@ class Config { } this.#flatOptions.nodeBin = this.execPath this.#flatOptions.npmBin = this.npmBin - process.emit('timeEnd', 'config:load:flatten') + timeEnd() return this.#flatOptions } @@ -233,37 +233,24 @@ class Config { throw new Error('attempting to load npm config multiple times') } - process.emit('time', 'config:load') // first load the defaults, which sets the global prefix - process.emit('time', 'config:load:defaults') this.loadDefaults() - process.emit('timeEnd', 'config:load:defaults') // next load the builtin config, as this sets new effective defaults - process.emit('time', 'config:load:builtin') await this.loadBuiltinConfig() - process.emit('timeEnd', 'config:load:builtin') // cli and env are not async, and can set the prefix, relevant to project - process.emit('time', 'config:load:cli') this.loadCLI() - process.emit('timeEnd', 'config:load:cli') - process.emit('time', 'config:load:env') this.loadEnv() - process.emit('timeEnd', 'config:load:env') // next project config, which can affect userconfig location - process.emit('time', 'config:load:project') await this.loadProjectConfig() - process.emit('timeEnd', 'config:load:project') + // then user config, which can affect globalconfig location - process.emit('time', 'config:load:user') await this.loadUserConfig() - process.emit('timeEnd', 'config:load:user') + // last but not least, global config file - process.emit('time', 'config:load:global') await this.loadGlobalConfig() - process.emit('timeEnd', 'config:load:global') // set this before calling setEnvs, so that we don't have to share // private attributes, as that module also does a bunch of get operations @@ -272,11 +259,7 @@ class Config { // set proper globalPrefix now that everything is loaded this.globalPrefix = this.get('prefix') - process.emit('time', 'config:load:setEnvs') this.setEnvs() - process.emit('timeEnd', 'config:load:setEnvs') - - process.emit('timeEnd', 'config:load') } loadDefaults () { @@ -574,7 +557,7 @@ class Config { const k = envReplace(key, this.env) const v = this.parseField(value, k) if (where !== 'default') { - this.#checkDeprecated(k, where, obj, [key, value]) + this.#checkDeprecated(k) if (this.definitions[key]?.exclusive) { for (const exclusive of this.definitions[key].exclusive) { if (!this.isDefault(exclusive)) { @@ -588,7 +571,7 @@ class Config { } } - #checkDeprecated (key, where, obj, kv) { + #checkDeprecated (key) { // XXX(npm9+) make this throw an error if (this.deprecated[key]) { log.warn('config', key, this.deprecated[key]) @@ -601,8 +584,8 @@ class Config { } async #loadFile (file, type) { - process.emit('time', 'config:load:file:' + file) // only catch the error from readFile, not from the loadObject call + log.silly(`config:load:file:${file}`) await readFile(file, 'utf8').then( data => { const parsedConfig = ini.parse(data) @@ -615,7 +598,6 @@ class Config { }, er => this.#loadObject(null, type, file, er) ) - process.emit('timeEnd', 'config:load:file:' + file) } loadBuiltinConfig () { @@ -757,7 +739,7 @@ class Config { const iniData = ini.stringify(conf.raw).trim() + '\n' if (!iniData.trim()) { // ignore the unlink error (eg, if file doesn't exist) - await unlink(conf.source).catch(er => {}) + await unlink(conf.source).catch(() => {}) return } const dir = dirname(conf.source) @@ -792,12 +774,9 @@ class Config { this.delete(`${nerfed}:keyfile`, level) } - setCredentialsByURI (uri, { token, username, password, email, certfile, keyfile }) { + setCredentialsByURI (uri, { token, username, password, certfile, keyfile }) { const nerfed = nerfDart(uri) - // email is either provided, a top level key, or nothing - email = email || this.get('email', 'user') - // field that hasn't been used as documented for a LONG time, // and as of npm 7.10.0, isn't used at all. We just always // send auth if we have it, only to the URIs under the nerf dart. diff --git a/deps/npm/node_modules/@npmcli/config/package.json b/deps/npm/node_modules/@npmcli/config/package.json index 797c32f7ee4a63..8c59bc3ae3dff6 100644 --- a/deps/npm/node_modules/@npmcli/config/package.json +++ b/deps/npm/node_modules/@npmcli/config/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/config", - "version": "8.2.2", + "version": "8.3.1", "files": [ "bin/", "lib/" @@ -9,7 +9,7 @@ "description": "Configuration management for the npm cli", "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/config" }, "author": "GitHub Inc.", @@ -40,7 +40,7 @@ "ci-info": "^4.0.0", "ini": "^4.1.2", "nopt": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.2.0", "read-package-json-fast": "^3.0.2", "semver": "^7.3.5", "walk-up-path": "^3.0.1" diff --git a/deps/npm/node_modules/@npmcli/disparity-colors/lib/index.js b/deps/npm/node_modules/@npmcli/disparity-colors/lib/index.js deleted file mode 100644 index 3d2aa56be92536..00000000000000 --- a/deps/npm/node_modules/@npmcli/disparity-colors/lib/index.js +++ /dev/null @@ -1,34 +0,0 @@ -const ansi = require('ansi-styles') - -const colors = { - removed: ansi.red, - added: ansi.green, - header: ansi.yellow, - section: ansi.magenta, -} - -function colorize (str, opts) { - let headerLength = (opts || {}).headerLength - if (typeof headerLength !== 'number' || Number.isNaN(headerLength)) { - headerLength = 2 - } - - const color = (colorStr, colorId) => { - const { open, close } = colors[colorId] - // avoid highlighting the "\n" (would highlight till the end of the line) - return colorStr.replace(/[^\n\r]+/g, open + '$&' + close) - } - - // this RegExp will include all the `\n` chars into the lines, easier to join - const lines = ((typeof str === 'string' && str) || '').split(/^/m) - - const start = color(lines.slice(0, headerLength).join(''), 'header') - const end = lines.slice(headerLength).join('') - .replace(/^-.*/gm, color('$&', 'removed')) - .replace(/^\+.*/gm, color('$&', 'added')) - .replace(/^@@.+@@/gm, color('$&', 'section')) - - return start + end -} - -module.exports = colorize diff --git a/deps/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles/index.js b/deps/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles/index.js deleted file mode 100644 index 5d82581a13f990..00000000000000 --- a/deps/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles/index.js +++ /dev/null @@ -1,163 +0,0 @@ -'use strict'; - -const wrapAnsi16 = (fn, offset) => (...args) => { - const code = fn(...args); - return `\u001B[${code + offset}m`; -}; - -const wrapAnsi256 = (fn, offset) => (...args) => { - const code = fn(...args); - return `\u001B[${38 + offset};5;${code}m`; -}; - -const wrapAnsi16m = (fn, offset) => (...args) => { - const rgb = fn(...args); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; -}; - -const ansi2ansi = n => n; -const rgb2rgb = (r, g, b) => [r, g, b]; - -const setLazyProperty = (object, property, get) => { - Object.defineProperty(object, property, { - get: () => { - const value = get(); - - Object.defineProperty(object, property, { - value, - enumerable: true, - configurable: true - }); - - return value; - }, - enumerable: true, - configurable: true - }); -}; - -/** @type {typeof import('color-convert')} */ -let colorConvert; -const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { - if (colorConvert === undefined) { - colorConvert = require('color-convert'); - } - - const offset = isBackground ? 10 : 0; - const styles = {}; - - for (const [sourceSpace, suite] of Object.entries(colorConvert)) { - const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace; - if (sourceSpace === targetSpace) { - styles[name] = wrap(identity, offset); - } else if (typeof suite === 'object') { - styles[name] = wrap(suite[targetSpace], offset); - } - } - - return styles; -}; - -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - - // Bright color - blackBright: [90, 39], - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], - - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; - - // Alias bright black as gray (and grey) - styles.color.gray = styles.color.blackBright; - styles.bgColor.bgGray = styles.bgColor.bgBlackBright; - styles.color.grey = styles.color.blackBright; - styles.bgColor.bgGrey = styles.bgColor.bgBlackBright; - - for (const [groupName, group] of Object.entries(styles)) { - for (const [styleName, style] of Object.entries(group)) { - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; - - group[styleName] = styles[styleName]; - - codes.set(style[0], style[1]); - } - - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); - } - - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); - - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; - - setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false)); - setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false)); - setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false)); - setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true)); - setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true)); - setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true)); - - return styles; -} - -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); diff --git a/deps/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles/license b/deps/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles/license deleted file mode 100644 index e7af2f77107d73..00000000000000 --- a/deps/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles/license +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/deps/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles/package.json b/deps/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles/package.json deleted file mode 100644 index 75393284d7e474..00000000000000 --- a/deps/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "ansi-styles", - "version": "4.3.0", - "description": "ANSI escape codes for styling strings in the terminal", - "license": "MIT", - "repository": "chalk/ansi-styles", - "funding": "https://github.com/chalk/ansi-styles?sponsor=1", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "engines": { - "node": ">=8" - }, - "scripts": { - "test": "xo && ava && tsd", - "screenshot": "svg-term --command='node screenshot' --out=screenshot.svg --padding=3 --width=55 --height=3 --at=1000 --no-cursor" - }, - "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "ansi", - "styles", - "color", - "colour", - "colors", - "terminal", - "console", - "cli", - "string", - "tty", - "escape", - "formatting", - "rgb", - "256", - "shell", - "xterm", - "log", - "logging", - "command-line", - "text" - ], - "dependencies": { - "color-convert": "^2.0.1" - }, - "devDependencies": { - "@types/color-convert": "^1.9.0", - "ava": "^2.3.0", - "svg-term-cli": "^2.1.1", - "tsd": "^0.11.0", - "xo": "^0.25.3" - } -} diff --git a/deps/npm/node_modules/@npmcli/disparity-colors/package.json b/deps/npm/node_modules/@npmcli/disparity-colors/package.json deleted file mode 100644 index 17eb4846c353c4..00000000000000 --- a/deps/npm/node_modules/@npmcli/disparity-colors/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "name": "@npmcli/disparity-colors", - "version": "3.0.0", - "main": "lib/index.js", - "files": [ - "bin/", - "lib/" - ], - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "description": "Colorizes unified diff output", - "repository": { - "type": "git", - "url": "https://github.com/npm/disparity-colors.git" - }, - "keywords": [ - "disparity", - "npm", - "npmcli", - "diff", - "char", - "unified", - "multiline", - "string", - "color", - "ansi", - "terminal", - "cli", - "tty" - ], - "author": "GitHub Inc.", - "contributors": [ - { - "name": "Ruy Adorno", - "url": "https://ruyadorno.com", - "twitter": "ruyadorno" - } - ], - "license": "ISC", - "scripts": { - "lint": "eslint \"**/*.js\"", - "pretest": "npm run lint", - "test": "tap", - "snap": "tap", - "postlint": "template-oss-check", - "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", - "posttest": "npm run lint" - }, - "tap": { - "check-coverage": true, - "nyc-arg": [ - "--exclude", - "tap-snapshots/**" - ] - }, - "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "4.5.1", - "tap": "^16.0.1" - }, - "dependencies": { - "ansi-styles": "^4.3.0" - }, - "templateOSS": { - "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.5.1" - } -} diff --git a/deps/npm/node_modules/@npmcli/git/lib/spawn.js b/deps/npm/node_modules/@npmcli/git/lib/spawn.js index 5e96eb5542b5a6..03c1cbde215477 100644 --- a/deps/npm/node_modules/@npmcli/git/lib/spawn.js +++ b/deps/npm/node_modules/@npmcli/git/lib/spawn.js @@ -1,6 +1,6 @@ const spawn = require('@npmcli/promise-spawn') const promiseRetry = require('promise-retry') -const log = require('proc-log') +const { log } = require('proc-log') const makeError = require('./make-error.js') const makeOpts = require('./opts.js') diff --git a/deps/npm/node_modules/@npmcli/git/package.json b/deps/npm/node_modules/@npmcli/git/package.json index 7493ec7fb0effb..f7117f13a9399c 100644 --- a/deps/npm/node_modules/@npmcli/git/package.json +++ b/deps/npm/node_modules/@npmcli/git/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/git", - "version": "5.0.5", + "version": "5.0.6", "main": "lib/index.js", "files": [ "bin/", @@ -40,7 +40,7 @@ "@npmcli/promise-spawn": "^7.0.0", "lru-cache": "^10.0.1", "npm-pick-manifest": "^9.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", "semver": "^7.3.5", diff --git a/deps/npm/node_modules/@npmcli/installed-package-contents/bin/index.js b/deps/npm/node_modules/@npmcli/installed-package-contents/bin/index.js new file mode 100755 index 00000000000000..7b83b23bf168c0 --- /dev/null +++ b/deps/npm/node_modules/@npmcli/installed-package-contents/bin/index.js @@ -0,0 +1,44 @@ +#! /usr/bin/env node + +const { relative } = require('path') +const pkgContents = require('../') + +const usage = `Usage: + installed-package-contents [-d --depth=] + +Lists the files installed for a package specified by . + +Options: + -d --depth= Provide a numeric value ("Infinity" is allowed) + to specify how deep in the file tree to traverse. + Default=1 + -h --help Show this usage information` + +const options = {} + +process.argv.slice(2).forEach(arg => { + let match + if ((match = arg.match(/^(?:--depth=|-d)([0-9]+|Infinity)/))) { + options.depth = +match[1] + } else if (arg === '-h' || arg === '--help') { + console.log(usage) + process.exit(0) + } else { + options.path = arg + } +}) + +if (!options.path) { + console.error('ERROR: no path provided') + console.error(usage) + process.exit(1) +} + +const cwd = process.cwd() + +pkgContents(options) + .then(list => list.sort().forEach(p => console.log(relative(cwd, p)))) + .catch(/* istanbul ignore next - pretty unusual */ er => { + console.error(er) + process.exit(1) + }) diff --git a/deps/npm/node_modules/@npmcli/installed-package-contents/lib/index.js b/deps/npm/node_modules/@npmcli/installed-package-contents/lib/index.js old mode 100755 new mode 100644 index 20b25c4bc8437d..ab1486cd01d003 --- a/deps/npm/node_modules/@npmcli/installed-package-contents/lib/index.js +++ b/deps/npm/node_modules/@npmcli/installed-package-contents/lib/index.js @@ -1,5 +1,3 @@ -#! /usr/bin/env node - // to GET CONTENTS for folder at PATH (which may be a PACKAGE): // - if PACKAGE, read path/package.json // - if bins in ../node_modules/.bin, add those to result @@ -19,53 +17,46 @@ // - add GET CONTENTS of bundled deps, PACKAGE=true, depth + 1 const bundled = require('npm-bundled') -const { promisify } = require('util') -const fs = require('fs') -const readFile = promisify(fs.readFile) -const readdir = promisify(fs.readdir) -const stat = promisify(fs.stat) -const lstat = promisify(fs.lstat) -const { relative, resolve, basename, dirname } = require('path') +const { readFile, readdir, stat } = require('fs/promises') +const { resolve, basename, dirname } = require('path') const normalizePackageBin = require('npm-normalize-package-bin') -const readPackage = ({ path, packageJsonCache }) => - packageJsonCache.has(path) ? Promise.resolve(packageJsonCache.get(path)) +const readPackage = ({ path, packageJsonCache }) => packageJsonCache.has(path) + ? Promise.resolve(packageJsonCache.get(path)) : readFile(path).then(json => { const pkg = normalizePackageBin(JSON.parse(json)) packageJsonCache.set(path, pkg) return pkg - }) - .catch(er => null) + }).catch(() => null) // just normalize bundle deps and bin, that's all we care about here. const normalized = Symbol('package data has been normalized') -const rpj = ({ path, packageJsonCache }) => - readPackage({ path, packageJsonCache }) - .then(pkg => { - if (!pkg || pkg[normalized]) { - return pkg - } - if (pkg.bundledDependencies && !pkg.bundleDependencies) { - pkg.bundleDependencies = pkg.bundledDependencies - delete pkg.bundledDependencies - } - const bd = pkg.bundleDependencies - if (bd === true) { - pkg.bundleDependencies = [ - ...Object.keys(pkg.dependencies || {}), - ...Object.keys(pkg.optionalDependencies || {}), - ] - } - if (typeof bd === 'object' && !Array.isArray(bd)) { - pkg.bundleDependencies = Object.keys(bd) - } - pkg[normalized] = true +const rpj = ({ path, packageJsonCache }) => readPackage({ path, packageJsonCache }) + .then(pkg => { + if (!pkg || pkg[normalized]) { return pkg - }) + } + if (pkg.bundledDependencies && !pkg.bundleDependencies) { + pkg.bundleDependencies = pkg.bundledDependencies + delete pkg.bundledDependencies + } + const bd = pkg.bundleDependencies + if (bd === true) { + pkg.bundleDependencies = [ + ...Object.keys(pkg.dependencies || {}), + ...Object.keys(pkg.optionalDependencies || {}), + ] + } + if (typeof bd === 'object' && !Array.isArray(bd)) { + pkg.bundleDependencies = Object.keys(bd) + } + pkg[normalized] = true + return pkg + }) const pkgContents = async ({ path, - depth, + depth = 1, currentDepth = 0, pkg = null, result = null, @@ -105,7 +96,7 @@ const pkgContents = async ({ }) const bins = await Promise.all( - binFiles.map(b => stat(b).then(() => b).catch((er) => null)) + binFiles.map(b => stat(b).then(() => b).catch(() => null)) ) bins.filter(b => b).forEach(b => result.add(b)) } @@ -136,18 +127,6 @@ const pkgContents = async ({ const recursePromises = [] - // if we didn't get withFileTypes support, tack that on - if (typeof dirEntries[0] === 'string') { - // use a map so we can return a promise, but we mutate dirEntries in place - // this is much slower than getting the entries from the readdir call, - // but polyfills support for node versions before 10.10 - await Promise.all(dirEntries.map(async (name, index) => { - const p = resolve(path, name) - const st = await lstat(p) - dirEntries[index] = Object.assign(st, { name }) - })) - } - for (const entry of dirEntries) { const p = resolve(path, entry.name) if (entry.isDirectory() === false) { @@ -195,48 +174,8 @@ const pkgContents = async ({ return result } -module.exports = ({ path, depth = 1, packageJsonCache }) => pkgContents({ +module.exports = ({ path, ...opts }) => pkgContents({ path: resolve(path), - depth, + ...opts, pkg: true, - packageJsonCache, }).then(results => [...results]) - -if (require.main === module) { - const options = { path: null, depth: 1 } - const usage = `Usage: - installed-package-contents [-d --depth=] - -Lists the files installed for a package specified by . - -Options: - -d --depth= Provide a numeric value ("Infinity" is allowed) - to specify how deep in the file tree to traverse. - Default=1 - -h --help Show this usage information` - - process.argv.slice(2).forEach(arg => { - let match - if ((match = arg.match(/^--depth=([0-9]+|Infinity)/)) || - (match = arg.match(/^-d([0-9]+|Infinity)/))) { - options.depth = +match[1] - } else if (arg === '-h' || arg === '--help') { - console.log(usage) - process.exit(0) - } else { - options.path = arg - } - }) - if (!options.path) { - console.error('ERROR: no path provided') - console.error(usage) - process.exit(1) - } - const cwd = process.cwd() - module.exports(options) - .then(list => list.sort().forEach(p => console.log(relative(cwd, p)))) - .catch(/* istanbul ignore next - pretty unusual */ er => { - console.error(er) - process.exit(1) - }) -} diff --git a/deps/npm/node_modules/@npmcli/installed-package-contents/package.json b/deps/npm/node_modules/@npmcli/installed-package-contents/package.json index 3554754123e618..132256430a6c18 100644 --- a/deps/npm/node_modules/@npmcli/installed-package-contents/package.json +++ b/deps/npm/node_modules/@npmcli/installed-package-contents/package.json @@ -1,17 +1,17 @@ { "name": "@npmcli/installed-package-contents", - "version": "2.0.2", + "version": "2.1.0", "description": "Get the list of files installed in a package in node_modules, including bundled dependencies", "author": "GitHub Inc.", "main": "lib/index.js", "bin": { - "installed-package-contents": "lib/index.js" + "installed-package-contents": "bin/index.js" }, "license": "ISC", "scripts": { "test": "tap", "snap": "tap", - "lint": "eslint \"**/*.js\"", + "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", "lintfix": "npm run lint -- --fix", @@ -19,8 +19,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.11.4", - "require-inject": "^1.4.4", + "@npmcli/template-oss": "4.21.4", "tap": "^16.3.0" }, "dependencies": { @@ -40,7 +39,8 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.11.4" + "version": "4.21.4", + "publish": true }, "tap": { "nyc-arg": [ diff --git a/deps/npm/node_modules/@npmcli/metavuln-calculator/lib/index.js b/deps/npm/node_modules/@npmcli/metavuln-calculator/lib/index.js index 668f55942c5065..2a4e08395e7edd 100644 --- a/deps/npm/node_modules/@npmcli/metavuln-calculator/lib/index.js +++ b/deps/npm/node_modules/@npmcli/metavuln-calculator/lib/index.js @@ -3,6 +3,7 @@ // class handles all the IO with the registry and cache. const pacote = require('pacote') const cacache = require('cacache') +const { time } = require('proc-log') const Advisory = require('./advisory.js') const { homedir } = require('os') const jsonParse = require('json-parse-even-better-errors') @@ -48,34 +49,33 @@ class Calculator { async [_calculate] (name, source) { const k = `security-advisory:${name}:${source.id}` - const t = `metavuln:calculate:${k}` - process.emit('time', t) + const timeEnd = time.start(`metavuln:calculate:${k}`) const advisory = new Advisory(name, source, this[_options]) // load packument and cached advisory const [cached, packument] = await Promise.all([ this[_cacheGet](advisory), this[_packument](name), ]) - process.emit('time', `metavuln:load:${k}`) + const timeEndLoad = time.start(`metavuln:load:${k}`) advisory.load(cached, packument) - process.emit('timeEnd', `metavuln:load:${k}`) + timeEndLoad() if (advisory.updated) { await this[_cachePut](advisory) } this[_advisories].set(k, advisory) - process.emit('timeEnd', t) + timeEnd() return advisory } async [_cachePut] (advisory) { const { name, id } = advisory const key = `security-advisory:${name}:${id}` - process.emit('time', `metavuln:cache:put:${key}`) + const timeEnd = time.start(`metavuln:cache:put:${key}`) const data = JSON.stringify(advisory) const options = { ...this[_options] } this[_cacheData].set(key, jsonParse(data)) await cacache.put(this[_cache], key, data, options).catch(() => {}) - process.emit('timeEnd', `metavuln:cache:put:${key}`) + timeEnd() } async [_cacheGet] (advisory) { @@ -87,12 +87,12 @@ class Calculator { return this[_cacheData].get(key) } - process.emit('time', `metavuln:cache:get:${key}`) + const timeEnd = time.start(`metavuln:cache:get:${key}`) const p = cacache.get(this[_cache], key, { ...this[_options] }) .catch(() => ({ data: '{}' })) .then(({ data }) => { data = jsonParse(data) - process.emit('timeEnd', `metavuln:cache:get:${key}`) + timeEnd() this[_cacheData].set(key, data) return data }) @@ -105,7 +105,7 @@ class Calculator { return this[_packuments].get(name) } - process.emit('time', `metavuln:packument:${name}`) + const timeEnd = time.start(`metavuln:packument:${name}`) const p = pacote.packument(name, { ...this[_options] }) .catch((er) => { // presumably not something from the registry. @@ -116,7 +116,7 @@ class Calculator { } }) .then(paku => { - process.emit('timeEnd', `metavuln:packument:${name}`) + timeEnd() this[_packuments].set(name, paku) return paku }) diff --git a/deps/npm/node_modules/@npmcli/metavuln-calculator/package.json b/deps/npm/node_modules/@npmcli/metavuln-calculator/package.json index 4d0af031d54148..74c23ad62bd7a5 100644 --- a/deps/npm/node_modules/@npmcli/metavuln-calculator/package.json +++ b/deps/npm/node_modules/@npmcli/metavuln-calculator/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/metavuln-calculator", - "version": "7.0.0", + "version": "7.1.0", "main": "lib/index.js", "files": [ "bin/", @@ -19,7 +19,7 @@ "snap": "tap", "postsnap": "npm run lint", "eslint": "eslint", - "lint": "eslint \"**/*.js\"", + "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "lintfix": "npm run lint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force" @@ -34,14 +34,15 @@ }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.18.0", + "@npmcli/template-oss": "4.21.4", "require-inject": "^1.4.4", "tap": "^16.0.1" }, "dependencies": { "cacache": "^18.0.0", "json-parse-even-better-errors": "^3.0.0", - "pacote": "^17.0.0", + "pacote": "^18.0.0", + "proc-log": "^4.1.0", "semver": "^7.3.5" }, "engines": { @@ -49,7 +50,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.18.0", + "version": "4.21.4", "publish": "true", "ciVersions": [ "16.14.0", diff --git a/deps/npm/node_modules/@npmcli/package-json/lib/index.js b/deps/npm/node_modules/@npmcli/package-json/lib/index.js index 0cc41c685a39e7..6d1b760727ba60 100644 --- a/deps/npm/node_modules/@npmcli/package-json/lib/index.js +++ b/deps/npm/node_modules/@npmcli/package-json/lib/index.js @@ -167,6 +167,12 @@ class PackageJson { return this } + fromContent (data) { + this.#manifest = data + this.#canSave = false + return this + } + // Load data from a comment // /**package { "name": "foo", "version": "1.2.3", ... } **/ fromComment (data) { diff --git a/deps/npm/node_modules/@npmcli/package-json/lib/normalize.js b/deps/npm/node_modules/@npmcli/package-json/lib/normalize.js index 350b3f3d7cb8f0..e3b37984884279 100644 --- a/deps/npm/node_modules/@npmcli/package-json/lib/normalize.js +++ b/deps/npm/node_modules/@npmcli/package-json/lib/normalize.js @@ -2,7 +2,7 @@ const valid = require('semver/functions/valid') const clean = require('semver/functions/clean') const fs = require('fs/promises') const path = require('path') -const log = require('proc-log') +const { log } = require('proc-log') /** * @type {import('hosted-git-info')} diff --git a/deps/npm/node_modules/@npmcli/package-json/package.json b/deps/npm/node_modules/@npmcli/package-json/package.json index 4f7a29d2e4c597..98236f604ecbd7 100644 --- a/deps/npm/node_modules/@npmcli/package-json/package.json +++ b/deps/npm/node_modules/@npmcli/package-json/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/package-json", - "version": "5.0.2", + "version": "5.1.0", "description": "Programmatic API to update package.json", "main": "lib/index.js", "files": [ @@ -25,7 +25,7 @@ "license": "ISC", "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.21.3", + "@npmcli/template-oss": "4.21.4", "read-package-json": "^7.0.0", "read-package-json-fast": "^3.0.2", "tap": "^16.0.1" @@ -36,7 +36,7 @@ "hosted-git-info": "^7.0.0", "json-parse-even-better-errors": "^3.0.0", "normalize-package-data": "^6.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.5.3" }, "repository": { @@ -48,7 +48,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.21.3", + "version": "4.21.4", "publish": "true" }, "tap": { diff --git a/deps/npm/node_modules/@npmcli/redact/lib/deep-map.js b/deps/npm/node_modules/@npmcli/redact/lib/deep-map.js new file mode 100644 index 00000000000000..ad042dbdfc5341 --- /dev/null +++ b/deps/npm/node_modules/@npmcli/redact/lib/deep-map.js @@ -0,0 +1,59 @@ +const deepMap = (input, handler = v => v, path = ['$'], seen = new Set([input])) => { + if (Array.isArray(input)) { + const result = [] + for (let i = 0; i < input.length; i++) { + const element = input[i] + const elementPath = [...path, i] + if (element instanceof Object) { + if (!seen.has(element)) { // avoid getting stuck in circular reference + seen.add(element) + result.push(deepMap(handler(element, elementPath), handler, elementPath, seen)) + } + } else { + result.push(handler(element, elementPath)) + } + } + return result + } + + if (input === null) { + return null + } else if (typeof input === 'object' || typeof input === 'function') { + const result = {} + + if (input instanceof Error) { + // `name` property is not included in `Object.getOwnPropertyNames(error)` + result.errorType = input.name + } + + for (const propertyName of Object.getOwnPropertyNames(input)) { + // skip logging internal properties + if (propertyName.startsWith('_')) { + continue + } + + try { + const property = input[propertyName] + const propertyPath = [...path, propertyName] + if (property instanceof Object) { + if (!seen.has(property)) { // avoid getting stuck in circular reference + seen.add(property) + result[propertyName] = deepMap( + handler(property, propertyPath), handler, propertyPath, seen + ) + } + } else { + result[propertyName] = handler(property, propertyPath) + } + } catch (err) { + // a getter may throw an error + result[propertyName] = `[error getting value: ${err.message}]` + } + } + return result + } + + return handler(input, path) +} + +module.exports = { deepMap } diff --git a/deps/npm/node_modules/@npmcli/redact/lib/index.js b/deps/npm/node_modules/@npmcli/redact/lib/index.js index e5b5e74157c2a3..9b10c7f6a0081d 100644 --- a/deps/npm/node_modules/@npmcli/redact/lib/index.js +++ b/deps/npm/node_modules/@npmcli/redact/lib/index.js @@ -1,29 +1,15 @@ -const { URL } = require('url') +const matchers = require('./matchers') +const { redactUrlPassword } = require('./utils') const REPLACE = '***' -const TOKEN_REGEX = /\bnpm_[a-zA-Z0-9]{36}\b/g -const GUID_REGEX = /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/g const redact = (value) => { if (typeof value !== 'string' || !value) { return value } - - let urlValue - try { - urlValue = new URL(value) - } catch { - // If it's not a URL then we can ignore all errors - } - - if (urlValue?.password) { - urlValue.password = REPLACE - value = urlValue.toString() - } - - return value - .replace(TOKEN_REGEX, `npm_${REPLACE}`) - .replace(GUID_REGEX, REPLACE) + return redactUrlPassword(value, REPLACE) + .replace(matchers.NPM_SECRET.pattern, `npm_${REPLACE}`) + .replace(matchers.UUID.pattern, REPLACE) } // split on \s|= similar to how nopt parses options @@ -49,7 +35,6 @@ const redactLog = (arg) => { } else if (Array.isArray(arg)) { return arg.map((a) => typeof a === 'string' ? splitAndRedact(a) : a) } - return arg } diff --git a/deps/npm/node_modules/@npmcli/redact/lib/matchers.js b/deps/npm/node_modules/@npmcli/redact/lib/matchers.js new file mode 100644 index 00000000000000..fe9b9071de8a16 --- /dev/null +++ b/deps/npm/node_modules/@npmcli/redact/lib/matchers.js @@ -0,0 +1,81 @@ +const TYPE_REGEX = 'regex' +const TYPE_URL = 'url' +const TYPE_PATH = 'path' + +const NPM_SECRET = { + type: TYPE_REGEX, + pattern: /\b(npms?_)[a-zA-Z0-9]{36,48}\b/gi, + replacement: `[REDACTED_NPM_SECRET]`, +} + +const AUTH_HEADER = { + type: TYPE_REGEX, + pattern: /\b(Basic\s+|Bearer\s+)[\w+=\-.]+\b/gi, + replacement: `[REDACTED_AUTH_HEADER]`, +} + +const JSON_WEB_TOKEN = { + type: TYPE_REGEX, + pattern: /\b[A-Za-z0-9-_]{10,}(?!\.\d+\.)\.[A-Za-z0-9-_]{3,}\.[A-Za-z0-9-_]{20,}\b/gi, + replacement: `[REDACTED_JSON_WEB_TOKEN]`, +} + +const UUID = { + type: TYPE_REGEX, + pattern: /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi, + replacement: `[REDACTED_UUID]`, +} + +const URL_MATCHER = { + type: TYPE_REGEX, + pattern: /(?:https?|ftp):\/\/[^\s/"$.?#].[^\s"]*/gi, + replacement: '[REDACTED_URL]', +} + +const DEEP_HEADER_AUTHORIZATION = { + type: TYPE_PATH, + predicate: ({ path }) => path.endsWith('.headers.authorization'), + replacement: '[REDACTED_HEADER_AUTHORIZATION]', +} + +const DEEP_HEADER_SET_COOKIE = { + type: TYPE_PATH, + predicate: ({ path }) => path.endsWith('.headers.set-cookie'), + replacement: '[REDACTED_HEADER_SET_COOKIE]', +} + +const REWRITE_REQUEST = { + type: TYPE_PATH, + predicate: ({ path }) => path.endsWith('.request'), + replacement: (input) => ({ + method: input?.method, + path: input?.path, + headers: input?.headers, + url: input?.url, + }), +} + +const REWRITE_RESPONSE = { + type: TYPE_PATH, + predicate: ({ path }) => path.endsWith('.response'), + replacement: (input) => ({ + data: input?.data, + status: input?.status, + headers: input?.headers, + }), +} + +module.exports = { + TYPE_REGEX, + TYPE_URL, + TYPE_PATH, + NPM_SECRET, + AUTH_HEADER, + JSON_WEB_TOKEN, + UUID, + URL_MATCHER, + DEEP_HEADER_AUTHORIZATION, + DEEP_HEADER_SET_COOKIE, + REWRITE_REQUEST, + REWRITE_RESPONSE, +} diff --git a/deps/npm/node_modules/@npmcli/redact/lib/server.js b/deps/npm/node_modules/@npmcli/redact/lib/server.js new file mode 100644 index 00000000000000..669e834da6131d --- /dev/null +++ b/deps/npm/node_modules/@npmcli/redact/lib/server.js @@ -0,0 +1,34 @@ +const { + AUTH_HEADER, + JSON_WEB_TOKEN, + NPM_SECRET, + DEEP_HEADER_AUTHORIZATION, + DEEP_HEADER_SET_COOKIE, + REWRITE_REQUEST, + REWRITE_RESPONSE, +} = require('./matchers') + +const { + redactUrlMatcher, + redactUrlPasswordMatcher, + redactMatchers, +} = require('./utils') + +const { deepMap } = require('./deep-map') + +const _redact = redactMatchers( + NPM_SECRET, + AUTH_HEADER, + JSON_WEB_TOKEN, + DEEP_HEADER_AUTHORIZATION, + DEEP_HEADER_SET_COOKIE, + REWRITE_REQUEST, + REWRITE_RESPONSE, + redactUrlMatcher( + redactUrlPasswordMatcher() + ) +) + +const redact = (input) => deepMap(input, (value, path) => _redact(value, { path })) + +module.exports = { redact } diff --git a/deps/npm/node_modules/@npmcli/redact/lib/utils.js b/deps/npm/node_modules/@npmcli/redact/lib/utils.js new file mode 100644 index 00000000000000..8395ab25fc373e --- /dev/null +++ b/deps/npm/node_modules/@npmcli/redact/lib/utils.js @@ -0,0 +1,202 @@ +const { + URL_MATCHER, + TYPE_URL, + TYPE_REGEX, + TYPE_PATH, +} = require('./matchers') + +/** + * creates a string of asterisks, + * this forces a minimum asterisk for security purposes + */ +const asterisk = (length = 0) => { + length = typeof length === 'string' ? length.length : length + if (length < 8) { + return '*'.repeat(8) + } + return '*'.repeat(length) +} + +/** + * escapes all special regex chars + * @see https://stackoverflow.com/a/9310752 + * @see https://github.com/tc39/proposal-regex-escaping + */ +const escapeRegExp = (text) => { + return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, `\\$&`) +} + +/** + * provieds a regex "or" of the url versions of a string + */ +const urlEncodeRegexGroup = (value) => { + const decoded = decodeURIComponent(value) + const encoded = encodeURIComponent(value) + const union = [...new Set([encoded, decoded, value])].map(escapeRegExp).join('|') + return union +} + +/** + * a tagged template literal that returns a regex ensures all variables are excaped + */ +const urlEncodeRegexTag = (strings, ...values) => { + let pattern = '' + for (let i = 0; i < values.length; i++) { + pattern += strings[i] + `(${urlEncodeRegexGroup(values[i])})` + } + pattern += strings[strings.length - 1] + return new RegExp(pattern) +} + +/** + * creates a matcher for redacting url hostname + */ +const redactUrlHostnameMatcher = ({ hostname, replacement } = {}) => ({ + type: TYPE_URL, + predicate: ({ url }) => url.hostname === hostname, + pattern: ({ url }) => { + return urlEncodeRegexTag`(^${url.protocol}//${url.username}:.+@)?${url.hostname}` + }, + replacement: `$1${replacement || asterisk()}`, +}) + +/** + * creates a matcher for redacting url search / query parameter values + */ +const redactUrlSearchParamsMatcher = ({ param, replacement } = {}) => ({ + type: TYPE_URL, + predicate: ({ url }) => url.searchParams.has(param), + pattern: ({ url }) => urlEncodeRegexTag`(${param}=)${url.searchParams.get(param)}`, + replacement: `$1${replacement || asterisk()}`, +}) + +/** creates a matcher for redacting the url password */ +const redactUrlPasswordMatcher = ({ replacement } = {}) => ({ + type: TYPE_URL, + predicate: ({ url }) => url.password, + pattern: ({ url }) => urlEncodeRegexTag`(^${url.protocol}//${url.username}:)${url.password}`, + replacement: `$1${replacement || asterisk()}`, +}) + +const redactUrlReplacement = (...matchers) => (subValue) => { + try { + const url = new URL(subValue) + return redactMatchers(...matchers)(subValue, { url }) + } catch (err) { + return subValue + } +} + +/** + * creates a matcher / submatcher for urls, this function allows you to first + * collect all urls within a larger string and then pass those urls to a + * submatcher + * + * @example + * console.log("this will first match all urls, then pass those urls to the password patcher") + * redactMatchers(redactUrlMatcher(redactUrlPasswordMatcher())) + * + * @example + * console.log( + * "this will assume you are passing in a string that is a url, and will redact the password" + * ) + * redactMatchers(redactUrlPasswordMatcher()) + * + */ +const redactUrlMatcher = (...matchers) => { + return { + ...URL_MATCHER, + replacement: redactUrlReplacement(...matchers), + } +} + +const matcherFunctions = { + [TYPE_REGEX]: (matcher) => (value) => { + if (typeof value === 'string') { + value = value.replace(matcher.pattern, matcher.replacement) + } + return value + }, + [TYPE_URL]: (matcher) => (value, ctx) => { + if (typeof value === 'string') { + try { + const url = ctx?.url || new URL(value) + const { predicate, pattern } = matcher + const predicateValue = predicate({ url }) + if (predicateValue) { + value = value.replace(pattern({ url }), matcher.replacement) + } + } catch (_e) { + return value + } + } + return value + }, + [TYPE_PATH]: (matcher) => (value, ctx) => { + const rawPath = ctx?.path + const path = rawPath.join('.').toLowerCase() + const { predicate, replacement } = matcher + const replace = typeof replacement === 'function' ? replacement : () => replacement + const shouldRun = predicate({ rawPath, path }) + if (shouldRun) { + value = replace(value, { rawPath, path }) + } + return value + }, +} + +/** converts a matcher to a function */ +const redactMatcher = (matcher) => { + return matcherFunctions[matcher.type](matcher) +} + +/** converts a series of matchers to a function */ +const redactMatchers = (...matchers) => (value, ctx) => { + const flatMatchers = matchers.flat() + return flatMatchers.reduce((result, matcher) => { + const fn = (typeof matcher === 'function') ? matcher : redactMatcher(matcher) + return fn(result, ctx) + }, value) +} + +/** + * replacement handler, keeping $1 (if it exists) and replacing the + * rest of the string with asterisks, maintaining string length + */ +const redactDynamicReplacement = () => (value, start) => { + if (typeof start === 'number') { + return asterisk(value) + } + return start + asterisk(value.substring(start.length).length) +} + +/** + * replacement handler, keeping $1 (if it exists) and replacing the + * rest of the string with a fixed number of asterisks + */ +const redactFixedReplacement = (length) => (_value, start) => { + if (typeof start === 'number') { + return asterisk(length) + } + return start + asterisk(length) +} + +const redactUrlPassword = (value, replacement) => { + return redactMatchers(redactUrlPasswordMatcher({ replacement }))(value) +} + +module.exports = { + asterisk, + escapeRegExp, + urlEncodeRegexGroup, + urlEncodeRegexTag, + redactUrlHostnameMatcher, + redactUrlSearchParamsMatcher, + redactUrlPasswordMatcher, + redactUrlMatcher, + redactUrlReplacement, + redactDynamicReplacement, + redactFixedReplacement, + redactMatchers, + redactUrlPassword, +} diff --git a/deps/npm/node_modules/@npmcli/redact/package.json b/deps/npm/node_modules/@npmcli/redact/package.json index 1fc64a4c02f28e..2bcee9ea0884b4 100644 --- a/deps/npm/node_modules/@npmcli/redact/package.json +++ b/deps/npm/node_modules/@npmcli/redact/package.json @@ -1,8 +1,13 @@ { "name": "@npmcli/redact", - "version": "1.1.0", + "version": "2.0.0", "description": "Redact sensitive npm information from output", "main": "lib/index.js", + "exports": { + ".": "./lib/index.js", + "./server": "./lib/server.js", + "./package.json": "./package.json" + }, "scripts": { "test": "tap", "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", @@ -32,7 +37,8 @@ "nyc-arg": [ "--exclude", "tap-snapshots/**" - ] + ], + "timeout": 120 }, "devDependencies": { "@npmcli/eslint-config": "^4.0.2", diff --git a/deps/npm/node_modules/@npmcli/run-script/lib/run-script-pkg.js b/deps/npm/node_modules/@npmcli/run-script/lib/run-script-pkg.js index ea33db56298586..9900c96315f85f 100644 --- a/deps/npm/node_modules/@npmcli/run-script/lib/run-script-pkg.js +++ b/deps/npm/node_modules/@npmcli/run-script/lib/run-script-pkg.js @@ -5,19 +5,6 @@ const { isNodeGypPackage, defaultGypInstallScript } = require('@npmcli/node-gyp' const signalManager = require('./signal-manager.js') const isServerPackage = require('./is-server-package.js') -// you wouldn't like me when I'm angry... -const bruce = (id, event, cmd, args) => { - let banner = id - ? `\n> ${id} ${event}\n` - : `\n> ${event}\n` - banner += `> ${cmd.trim().replace(/\n/g, '\n> ')}` - if (args.length) { - banner += ` ${args.join(' ')}` - } - banner += '\n' - return banner -} - const runScriptPkg = async options => { const { event, @@ -29,8 +16,6 @@ const runScriptPkg = async options => { pkg, args = [], stdioString, - // note: only used when stdio:inherit - banner = true, // how long to wait for a process.kill signal // only exposed here so that we can make the test go a bit faster. signalTimeout = 500, @@ -59,9 +44,22 @@ const runScriptPkg = async options => { return { code: 0, signal: null } } - if (stdio === 'inherit' && banner !== false) { - // we're dumping to the parent's stdout, so print the banner - console.log(bruce(pkg._id, event, cmd, args)) + let inputEnd = () => {} + if (stdio === 'inherit') { + let banner + if (pkg._id) { + banner = `\n> ${pkg._id} ${event}\n` + } else { + banner = `\n> ${event}\n` + } + banner += `> ${cmd.trim().replace(/\n/g, '\n> ')}` + if (args.length) { + banner += ` ${args.join(' ')}` + } + banner += '\n' + const { output, input } = require('proc-log') + output.standard(banner) + inputEnd = input.start() } const [spawnShell, spawnArgs, spawnOpts] = makeSpawnArgs({ @@ -108,7 +106,7 @@ const runScriptPkg = async options => { } else { throw er } - }) + }).finally(inputEnd) } module.exports = runScriptPkg diff --git a/deps/npm/node_modules/@npmcli/run-script/package.json b/deps/npm/node_modules/@npmcli/run-script/package.json index 1c98b1b170e265..8a83e726fbeb2c 100644 --- a/deps/npm/node_modules/@npmcli/run-script/package.json +++ b/deps/npm/node_modules/@npmcli/run-script/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/run-script", - "version": "7.0.4", + "version": "8.1.0", "description": "Run a lifecycle script for a package (descendant of npm-lifecycle)", "author": "GitHub Inc.", "license": "ISC", @@ -16,7 +16,7 @@ }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.21.3", + "@npmcli/template-oss": "4.21.4", "spawk": "^1.8.1", "tap": "^16.0.1" }, @@ -25,6 +25,7 @@ "@npmcli/package-json": "^5.0.0", "@npmcli/promise-spawn": "^7.0.0", "node-gyp": "^10.0.0", + "proc-log": "^4.0.0", "which": "^4.0.0" }, "files": [ @@ -41,7 +42,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.21.3", + "version": "4.21.4", "publish": "true" }, "tap": { diff --git a/deps/npm/node_modules/are-we-there-yet/LICENSE.md b/deps/npm/node_modules/are-we-there-yet/LICENSE.md deleted file mode 100644 index 845be76f64e789..00000000000000 --- a/deps/npm/node_modules/are-we-there-yet/LICENSE.md +++ /dev/null @@ -1,18 +0,0 @@ -ISC License - -Copyright npm, Inc. - -Permission to use, copy, modify, and/or distribute this -software for any purpose with or without fee is hereby -granted, provided that the above copyright notice and this -permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO -EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE -USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/deps/npm/node_modules/are-we-there-yet/lib/index.js b/deps/npm/node_modules/are-we-there-yet/lib/index.js deleted file mode 100644 index 57d8743fdad177..00000000000000 --- a/deps/npm/node_modules/are-we-there-yet/lib/index.js +++ /dev/null @@ -1,4 +0,0 @@ -'use strict' -exports.TrackerGroup = require('./tracker-group.js') -exports.Tracker = require('./tracker.js') -exports.TrackerStream = require('./tracker-stream.js') diff --git a/deps/npm/node_modules/are-we-there-yet/lib/tracker-base.js b/deps/npm/node_modules/are-we-there-yet/lib/tracker-base.js deleted file mode 100644 index 1b5e0dc30c49bb..00000000000000 --- a/deps/npm/node_modules/are-we-there-yet/lib/tracker-base.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' -const EventEmitter = require('events') - -let trackerId = 0 -class TrackerBase extends EventEmitter { - constructor (name) { - super() - this.id = ++trackerId - this.name = name - } -} - -module.exports = TrackerBase diff --git a/deps/npm/node_modules/are-we-there-yet/lib/tracker-group.js b/deps/npm/node_modules/are-we-there-yet/lib/tracker-group.js deleted file mode 100644 index 162c22584cdc53..00000000000000 --- a/deps/npm/node_modules/are-we-there-yet/lib/tracker-group.js +++ /dev/null @@ -1,112 +0,0 @@ -'use strict' -const TrackerBase = require('./tracker-base.js') -const Tracker = require('./tracker.js') -const TrackerStream = require('./tracker-stream.js') - -class TrackerGroup extends TrackerBase { - parentGroup = null - trackers = [] - completion = {} - weight = {} - totalWeight = 0 - finished = false - bubbleChange = bubbleChange(this) - - nameInTree () { - var names = [] - var from = this - while (from) { - names.unshift(from.name) - from = from.parentGroup - } - return names.join('/') - } - - addUnit (unit, weight) { - if (unit.addUnit) { - var toTest = this - while (toTest) { - if (unit === toTest) { - throw new Error( - 'Attempted to add tracker group ' + - unit.name + ' to tree that already includes it ' + - this.nameInTree(this)) - } - toTest = toTest.parentGroup - } - unit.parentGroup = this - } - this.weight[unit.id] = weight || 1 - this.totalWeight += this.weight[unit.id] - this.trackers.push(unit) - this.completion[unit.id] = unit.completed() - unit.on('change', this.bubbleChange) - if (!this.finished) { - this.emit('change', unit.name, this.completion[unit.id], unit) - } - return unit - } - - completed () { - if (this.trackers.length === 0) { - return 0 - } - var valPerWeight = 1 / this.totalWeight - var completed = 0 - for (var ii = 0; ii < this.trackers.length; ii++) { - var trackerId = this.trackers[ii].id - completed += - valPerWeight * this.weight[trackerId] * this.completion[trackerId] - } - return completed - } - - newGroup (name, weight) { - return this.addUnit(new TrackerGroup(name), weight) - } - - newItem (name, todo, weight) { - return this.addUnit(new Tracker(name, todo), weight) - } - - newStream (name, todo, weight) { - return this.addUnit(new TrackerStream(name, todo), weight) - } - - finish () { - this.finished = true - if (!this.trackers.length) { - this.addUnit(new Tracker(), 1, true) - } - for (var ii = 0; ii < this.trackers.length; ii++) { - var tracker = this.trackers[ii] - tracker.finish() - tracker.removeListener('change', this.bubbleChange) - } - this.emit('change', this.name, 1, this) - } - - debug (depth = 0) { - const indent = ' '.repeat(depth) - let output = `${indent}${this.name || 'top'}: ${this.completed()}\n` - - this.trackers.forEach(function (tracker) { - output += tracker instanceof TrackerGroup - ? tracker.debug(depth + 1) - : `${indent} ${tracker.name}: ${tracker.completed()}\n` - }) - return output - } -} - -function bubbleChange (trackerGroup) { - return function (name, completed, tracker) { - trackerGroup.completion[tracker.id] = completed - if (trackerGroup.finished) { - return - } - trackerGroup.emit('change', name || trackerGroup.name, trackerGroup.completed(), trackerGroup) - } -} - -module.exports = TrackerGroup diff --git a/deps/npm/node_modules/are-we-there-yet/lib/tracker-stream.js b/deps/npm/node_modules/are-we-there-yet/lib/tracker-stream.js deleted file mode 100644 index 75e44df309150f..00000000000000 --- a/deps/npm/node_modules/are-we-there-yet/lib/tracker-stream.js +++ /dev/null @@ -1,42 +0,0 @@ -'use strict' -const stream = require('stream') -const Tracker = require('./tracker.js') - -class TrackerStream extends stream.Transform { - constructor (name, size, options) { - super(options) - this.tracker = new Tracker(name, size) - this.name = name - this.id = this.tracker.id - this.tracker.on('change', this.trackerChange.bind(this)) - } - - trackerChange (name, completion) { - this.emit('change', name, completion, this) - } - - _transform (data, encoding, cb) { - this.tracker.completeWork(data.length ? data.length : 1) - this.push(data) - cb() - } - - _flush (cb) { - this.tracker.finish() - cb() - } - - completed () { - return this.tracker.completed() - } - - addWork (work) { - return this.tracker.addWork(work) - } - - finish () { - return this.tracker.finish() - } -} - -module.exports = TrackerStream diff --git a/deps/npm/node_modules/are-we-there-yet/lib/tracker.js b/deps/npm/node_modules/are-we-there-yet/lib/tracker.js deleted file mode 100644 index 02e879ce6e3e26..00000000000000 --- a/deps/npm/node_modules/are-we-there-yet/lib/tracker.js +++ /dev/null @@ -1,34 +0,0 @@ -'use strict' -const TrackerBase = require('./tracker-base.js') - -class Tracker extends TrackerBase { - constructor (name, todo) { - super(name) - this.workDone = 0 - this.workTodo = todo || 0 - } - - completed () { - return this.workTodo === 0 ? 0 : this.workDone / this.workTodo - } - - addWork (work) { - this.workTodo += work - this.emit('change', this.name, this.completed(), this) - } - - completeWork (work) { - this.workDone += work - if (this.workDone > this.workTodo) { - this.workDone = this.workTodo - } - this.emit('change', this.name, this.completed(), this) - } - - finish () { - this.workTodo = this.workDone = 1 - this.emit('change', this.name, 1, this) - } -} - -module.exports = Tracker diff --git a/deps/npm/node_modules/cli-table3/LICENSE b/deps/npm/node_modules/cli-table3/LICENSE deleted file mode 100644 index a09b7de012ac85..00000000000000 --- a/deps/npm/node_modules/cli-table3/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2014 James Talmage - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/deps/npm/node_modules/cli-table3/index.js b/deps/npm/node_modules/cli-table3/index.js deleted file mode 100644 index b49d920dd3ef69..00000000000000 --- a/deps/npm/node_modules/cli-table3/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./src/table'); \ No newline at end of file diff --git a/deps/npm/node_modules/cli-table3/package.json b/deps/npm/node_modules/cli-table3/package.json deleted file mode 100644 index 0bd5d31d102463..00000000000000 --- a/deps/npm/node_modules/cli-table3/package.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "name": "cli-table3", - "version": "0.6.4", - "description": "Pretty unicode tables for the command line. Based on the original cli-table.", - "main": "index.js", - "types": "index.d.ts", - "files": [ - "src/", - "index.d.ts", - "index.js" - ], - "directories": { - "test": "test" - }, - "dependencies": { - "string-width": "^4.2.0" - }, - "devDependencies": { - "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", - "jest-runner-eslint": "^0.7.0", - "lerna-changelog": "^1.0.1", - "prettier": "2.3.2" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - }, - "scripts": { - "changelog": "lerna-changelog", - "docs": "node ./scripts/update-docs.js", - "prettier": "prettier --write '{examples,lib,scripts,src,test}/**/*.js'", - "test": "jest --color", - "test:watch": "jest --color --watchAll --notify" - }, - "repository": { - "type": "git", - "url": "https://github.com/cli-table/cli-table3.git" - }, - "keywords": [ - "node", - "command", - "line", - "cli", - "table", - "tables", - "tabular", - "unicode", - "colors", - "grid" - ], - "author": "James Talmage", - "license": "MIT", - "bugs": { - "url": "https://github.com/cli-table/cli-table3/issues" - }, - "homepage": "https://github.com/cli-table/cli-table3", - "engines": { - "node": "10.* || >= 12.*" - }, - "changelog": { - "repo": "cli-table/cli-table3", - "labels": { - "breaking": ":boom: Breaking Change", - "enhancement": ":rocket: Enhancement", - "bug": ":bug: Bug Fix", - "documentation": ":memo: Documentation", - "internal": ":house: Internal" - } - }, - "jest": { - "projects": [ - { - "displayName": "test", - "testMatch": [ - "/test/**/*.js" - ] - }, - { - "runner": "jest-runner-eslint", - "displayName": "lint", - "testMatch": [ - "/examples/**/*.js", - "/lib/**/*.js", - "/scripts/**/*.js", - "/src/**/*.js", - "/test/**/*.js" - ] - } - ] - }, - "prettier": { - "printWidth": 120, - "tabWidth": 2, - "singleQuote": true, - "trailingComma": "es5" - } -} diff --git a/deps/npm/node_modules/cli-table3/src/cell.js b/deps/npm/node_modules/cli-table3/src/cell.js deleted file mode 100644 index 8c3df35d194076..00000000000000 --- a/deps/npm/node_modules/cli-table3/src/cell.js +++ /dev/null @@ -1,409 +0,0 @@ -const { info, debug } = require('./debug'); -const utils = require('./utils'); - -class Cell { - /** - * A representation of a cell within the table. - * Implementations must have `init` and `draw` methods, - * as well as `colSpan`, `rowSpan`, `desiredHeight` and `desiredWidth` properties. - * @param options - * @constructor - */ - constructor(options) { - this.setOptions(options); - - /** - * Each cell will have it's `x` and `y` values set by the `layout-manager` prior to - * `init` being called; - * @type {Number} - */ - this.x = null; - this.y = null; - } - - setOptions(options) { - if (['boolean', 'number', 'string'].indexOf(typeof options) !== -1) { - options = { content: '' + options }; - } - options = options || {}; - this.options = options; - let content = options.content; - if (['boolean', 'number', 'string'].indexOf(typeof content) !== -1) { - this.content = String(content); - } else if (!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) { - this.cells = cells; - - let optionsChars = this.options.chars || {}; - let tableChars = tableOptions.chars; - let chars = (this.chars = {}); - CHAR_NAMES.forEach(function (name) { - setOption(optionsChars, tableChars, name, chars); - }); - - this.truncate = this.options.truncate || tableOptions.truncate; - - let style = (this.options.style = this.options.style || {}); - let tableStyle = tableOptions.style; - setOption(style, tableStyle, 'padding-left', this); - setOption(style, tableStyle, 'padding-right', this); - this.head = style.head || tableStyle.head; - this.border = style.border || tableStyle.border; - - 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) { - const tableWordWrap = tableOptions.wordWrap || tableOptions.textWrap; - const { wordWrap = tableWordWrap } = this.options; - if (this.fixedWidth && wordWrap) { - this.fixedWidth -= this.paddingLeft + this.paddingRight; - if (this.colSpan) { - let i = 1; - while (i < this.colSpan) { - this.fixedWidth += tableOptions.colWidths[this.x + i]; - i++; - } - } - const { wrapOnWordBoundary: tableWrapOnWordBoundary = true } = tableOptions; - const { wrapOnWordBoundary = tableWrapOnWordBoundary } = this.options; - return this.wrapLines(utils.wordWrap(this.fixedWidth, this.content, wrapOnWordBoundary)); - } - return this.wrapLines(this.content.split('\n')); - } - - wrapLines(computedLines) { - const lines = utils.colorizeLines(computedLines); - if (this.href) { - return lines.map((line) => utils.hyperlink(this.href, line)); - } - return lines; - } - - /** - * Initializes the Cells data structure. - * - * @param tableOptions - A fully populated set of tableOptions. - * In addition to the standard default values, tableOptions must have fully populated the - * `colWidths` and `rowWidths` arrays. Those arrays must have lengths equal to the number - * of columns or rows (respectively) in this table, and each array item must be a Number. - * - */ - init(tableOptions) { - let x = this.x; - let y = this.y; - this.widths = tableOptions.colWidths.slice(x, x + this.colSpan); - this.heights = tableOptions.rowHeights.slice(y, y + this.rowSpan); - this.width = this.widths.reduce(sumPlusOne, -1); - this.height = this.heights.reduce(sumPlusOne, -1); - - this.hAlign = this.options.hAlign || tableOptions.colAligns[x]; - this.vAlign = this.options.vAlign || tableOptions.rowAligns[y]; - - this.drawRight = x + this.colSpan == tableOptions.colWidths.length; - } - - /** - * Draws the given line of the cell. - * This default implementation defers to methods `drawTop`, `drawBottom`, `drawLine` and `drawEmpty`. - * @param lineNum - can be `top`, `bottom` or a numerical line number. - * @param spanningCell - will be a number if being called from a RowSpanCell, and will represent how - * many rows below it's being called from. Otherwise it's undefined. - * @returns {String} The representation of this line. - */ - 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) { - case 'center': - padTop = Math.ceil(padLen / 2); - break; - case 'bottom': - padTop = padLen; - break; - default: - padTop = 0; - } - if (lineNum < padTop || lineNum >= padTop + this.lines.length) { - return this.drawEmpty(this.drawRight, spanningCell); - } - let forceTruncation = this.lines.length > this.height && lineNum + 1 >= this.height; - return this.drawLine(lineNum - padTop, this.drawRight, forceTruncation, spanningCell); - } - - /** - * Renders the top line of the cell. - * @param drawRight - true if this method should render the right edge of the cell. - * @returns {String} - */ - drawTop(drawRight) { - let content = []; - if (this.cells) { - //TODO: cells should always exist - some tests don't fill it in though - this.widths.forEach(function (width, index) { - content.push(this._topLeftChar(index)); - content.push(utils.repeat(this.chars[this.y == 0 ? 'top' : 'mid'], width)); - }, this); - } else { - content.push(this._topLeftChar(0)); - content.push(utils.repeat(this.chars[this.y == 0 ? 'top' : 'mid'], this.width)); - } - if (drawRight) { - content.push(this.chars[this.y == 0 ? 'topRight' : 'rightMid']); - } - return this.wrapWithStyleColors('border', content.join('')); - } - - _topLeftChar(offset) { - let x = this.x + offset; - let leftChar; - if (this.y == 0) { - leftChar = x == 0 ? 'topLeft' : offset == 0 ? 'topMid' : 'top'; - } else { - if (x == 0) { - leftChar = 'leftMid'; - } else { - leftChar = offset == 0 ? 'midMid' : 'bottomMid'; - if (this.cells) { - //TODO: cells should always exist - some tests don't fill it in though - let spanAbove = this.cells[this.y - 1][x] instanceof Cell.ColSpanCell; - if (spanAbove) { - leftChar = offset == 0 ? 'topMid' : 'mid'; - } - if (offset == 0) { - let i = 1; - while (this.cells[this.y][x - i] instanceof Cell.ColSpanCell) { - i++; - } - if (this.cells[this.y][x - i] instanceof Cell.RowSpanCell) { - leftChar = 'leftMid'; - } - } - } - } - } - return this.chars[leftChar]; - } - - wrapWithStyleColors(styleProperty, content) { - if (this[styleProperty] && this[styleProperty].length) { - try { - let colors = require('@colors/colors/safe'); - for (let i = this[styleProperty].length - 1; i >= 0; i--) { - colors = colors[this[styleProperty][i]]; - } - return colors(content); - } catch (e) { - return content; - } - } else { - return content; - } - } - - /** - * Renders a line of text. - * @param lineNum - Which line of text to render. This is not necessarily the line within the cell. - * There may be top-padding above the first line of text. - * @param drawRight - true if this method should render the right edge of the cell. - * @param forceTruncationSymbol - `true` if the rendered text should end with the truncation symbol even - * if the text fits. This is used when the cell is vertically truncated. If `false` the text should - * only include the truncation symbol if the text will not fit horizontally within the cell width. - * @param spanningCell - a number of if being called from a RowSpanCell. (how many rows below). otherwise undefined. - * @returns {String} - */ - drawLine(lineNum, drawRight, forceTruncationSymbol, spanningCell) { - let left = this.chars[this.x == 0 ? 'left' : 'middle']; - if (this.x && spanningCell && this.cells) { - let cellLeft = this.cells[this.y + spanningCell][this.x - 1]; - while (cellLeft instanceof ColSpanCell) { - cellLeft = this.cells[cellLeft.y][cellLeft.x - 1]; - } - if (!(cellLeft instanceof RowSpanCell)) { - left = this.chars['rightMid']; - } - } - let leftPadding = utils.repeat(' ', this.paddingLeft); - let right = drawRight ? this.chars['right'] : ''; - let rightPadding = utils.repeat(' ', this.paddingRight); - let line = this.lines[lineNum]; - let len = this.width - (this.paddingLeft + this.paddingRight); - if (forceTruncationSymbol) line += this.truncate || '…'; - let content = utils.truncate(line, len, this.truncate); - content = utils.pad(content, len, ' ', this.hAlign); - content = leftPadding + content + rightPadding; - return this.stylizeLine(left, content, right); - } - - stylizeLine(left, content, right) { - left = this.wrapWithStyleColors('border', left); - right = this.wrapWithStyleColors('border', right); - if (this.y === 0) { - content = this.wrapWithStyleColors('head', content); - } - return left + content + right; - } - - /** - * Renders the bottom line of the cell. - * @param drawRight - true if this method should render the right edge of the cell. - * @returns {String} - */ - drawBottom(drawRight) { - let left = this.chars[this.x == 0 ? 'bottomLeft' : 'bottomMid']; - let content = utils.repeat(this.chars.bottom, this.width); - let right = drawRight ? this.chars['bottomRight'] : ''; - return this.wrapWithStyleColors('border', left + content + right); - } - - /** - * Renders a blank line of text within the cell. Used for top and/or bottom padding. - * @param drawRight - true if this method should render the right edge of the cell. - * @param spanningCell - a number of if being called from a RowSpanCell. (how many rows below). otherwise undefined. - * @returns {String} - */ - drawEmpty(drawRight, spanningCell) { - let left = this.chars[this.x == 0 ? 'left' : 'middle']; - if (this.x && spanningCell && this.cells) { - let cellLeft = this.cells[this.y + spanningCell][this.x - 1]; - while (cellLeft instanceof ColSpanCell) { - cellLeft = this.cells[cellLeft.y][cellLeft.x - 1]; - } - if (!(cellLeft instanceof RowSpanCell)) { - left = this.chars['rightMid']; - } - } - let right = drawRight ? this.chars['right'] : ''; - let content = utils.repeat(' ', this.width); - return this.stylizeLine(left, content, right); - } -} - -class ColSpanCell { - /** - * A Cell that doesn't do anything. It just draws empty lines. - * Used as a placeholder in column spanning. - * @constructor - */ - constructor() {} - - draw(lineNum) { - if (typeof lineNum === 'number') { - debug(`${this.y}-${this.x}: 1x1 ColSpanCell`); - } - return ''; - } - - init() {} - - mergeTableOptions() {} -} - -class RowSpanCell { - /** - * A placeholder Cell for a Cell that spans multiple rows. - * It delegates rendering to the original cell, but adds the appropriate offset. - * @param originalCell - * @constructor - */ - constructor(originalCell) { - this.originalCell = originalCell; - } - - init(tableOptions) { - let y = this.y; - let originalY = this.originalCell.y; - this.cellOffset = y - originalY; - this.offset = findDimension(tableOptions.rowHeights, originalY, this.cellOffset); - } - - draw(lineNum) { - if (lineNum == 'top') { - return this.originalCell.draw(this.offset, this.cellOffset); - } - 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] = firstDefined(objA[nameA], objA[nameB], objB[nameA], objB[nameB]); - } else { - targetObj[nameB] = firstDefined(objA[nameB], objB[nameB]); - } -} - -function findDimension(dimensionTable, startingIndex, span) { - let ret = dimensionTable[startingIndex]; - for (let i = 1; i < span; i++) { - ret += 1 + dimensionTable[startingIndex + i]; - } - return ret; -} - -function sumPlusOne(a, b) { - return a + b + 1; -} - -let CHAR_NAMES = [ - 'top', - 'top-mid', - 'top-left', - 'top-right', - 'bottom', - 'bottom-mid', - 'bottom-left', - 'bottom-right', - 'left', - 'left-mid', - 'mid', - 'mid-mid', - 'right', - 'right-mid', - 'middle', -]; - -module.exports = Cell; -module.exports.ColSpanCell = ColSpanCell; -module.exports.RowSpanCell = RowSpanCell; diff --git a/deps/npm/node_modules/cli-table3/src/debug.js b/deps/npm/node_modules/cli-table3/src/debug.js deleted file mode 100644 index 6acfb030321597..00000000000000 --- a/deps/npm/node_modules/cli-table3/src/debug.js +++ /dev/null @@ -1,28 +0,0 @@ -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/deps/npm/node_modules/cli-table3/src/layout-manager.js b/deps/npm/node_modules/cli-table3/src/layout-manager.js deleted file mode 100644 index 3937452274d721..00000000000000 --- a/deps/npm/node_modules/cli-table3/src/layout-manager.js +++ /dev/null @@ -1,254 +0,0 @@ -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 col = 0; - row.forEach(function (cell) { - cell.y = rowIndex; - // 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; - } - } - col = cell.x + colSpan; - }); - Object.keys(alloc).forEach((idx) => { - alloc[idx]--; - if (alloc[idx] < 1) delete alloc[idx]; - }); - }); - } - - function maxWidth(table) { - let mw = 0; - table.forEach(function (row) { - row.forEach(function (cell) { - mw = Math.max(mw, cell.x + (cell.colSpan || 1)); - }); - }); - return mw; - } - - function maxHeight(table) { - return table.length; - } - - function cellsConflict(cell1, cell2) { - let yMin1 = cell1.y; - let yMax1 = cell1.y - 1 + (cell1.rowSpan || 1); - let yMin2 = cell2.y; - let yMax2 = cell2.y - 1 + (cell2.rowSpan || 1); - let yConflict = !(yMin1 > yMax2 || yMin2 > yMax1); - - let xMin1 = cell1.x; - let xMax1 = cell1.x - 1 + (cell1.colSpan || 1); - let xMin2 = cell2.x; - let xMax2 = cell2.x - 1 + (cell2.colSpan || 1); - let xConflict = !(xMin1 > xMax2 || xMin2 > xMax1); - - return yConflict && xConflict; - } - - function conflictExists(rows, x, y) { - let i_max = Math.min(rows.length - 1, y); - let cell = { x: x, y: y }; - for (let i = 0; i <= i_max; i++) { - let row = rows[i]; - for (let j = 0; j < row.length; j++) { - if (cellsConflict(cell, row[j])) { - return true; - } - } - } - return false; - } - - function allBlank(rows, y, xMin, xMax) { - for (let x = xMin; x < xMax; x++) { - if (conflictExists(rows, x, y)) { - return false; - } - } - return true; - } - - function addRowSpanCells(table) { - table.forEach(function (row, rowIndex) { - row.forEach(function (cell) { - for (let i = 1; i < cell.rowSpan; i++) { - let rowSpanCell = new RowSpanCell(cell); - rowSpanCell.x = cell.x; - rowSpanCell.y = cell.y + i; - rowSpanCell.colSpan = cell.colSpan; - insertCell(rowSpanCell, table[rowIndex + i]); - } - }); - }); - } - - function addColSpanCells(cellRows) { - for (let rowIndex = cellRows.length - 1; rowIndex >= 0; rowIndex--) { - let cellColumns = cellRows[rowIndex]; - for (let columnIndex = 0; columnIndex < cellColumns.length; columnIndex++) { - let cell = cellColumns[columnIndex]; - for (let k = 1; k < cell.colSpan; k++) { - let colSpanCell = new ColSpanCell(); - colSpanCell.x = cell.x + k; - colSpanCell.y = cell.y; - cellColumns.splice(columnIndex + 1, 0, colSpanCell); - } - } - } - } - - function insertCell(cell, row) { - let x = 0; - while (x < row.length && row[x].x < cell.x) { - x++; - } - row.splice(x, 0, 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)) { - let opts = { x: x, y: y, colSpan: 1, rowSpan: 1 }; - x++; - while (x < w_max && !conflictExists(table, x, y)) { - opts.colSpan++; - x++; - } - let y2 = y + 1; - while (y2 < h_max && allBlank(table, y2, opts.x, opts.x + opts.colSpan)) { - 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]); - } - } - } - } - - function generateCells(rows) { - return rows.map(function (row) { - if (!Array.isArray(row)) { - let key = Object.keys(row)[0]; - row = row[key]; - if (Array.isArray(row)) { - row = row.slice(); - row.unshift(key); - } else { - row = [key, row]; - } - } - return row.map(function (cell) { - return new Cell(cell); - }); - }); - } - - function makeTableLayout(rows) { - let cellRows = generateCells(rows); - layoutTable(cellRows); - fillInTable(cellRows); - addRowSpanCells(cellRows); - addColSpanCells(cellRows); - return cellRows; - } - - module.exports = { - makeTableLayout: makeTableLayout, - layoutTable: layoutTable, - addRowSpanCells: addRowSpanCells, - maxWidth: maxWidth, - fillInTable: fillInTable, - computeWidths: makeComputeWidths('colSpan', 'desiredWidth', 'x', 1), - computeHeights: makeComputeWidths('rowSpan', 'desiredHeight', 'y', 1), - }; -})(); - -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) { - spanners.push(cell); - } else { - result[cell[x]] = Math.max(result[cell[x]] || 0, cell[desiredWidth] || 0, forcedMin); - } - }); - }); - - vals.forEach(function (val, index) { - if (typeof val === 'number') { - result[index] = val; - } - }); - - //spanners.forEach(function(cell){ - for (let k = spanners.length - 1; k >= 0; k--) { - let cell = spanners[k]; - let span = cell[colSpan]; - let col = cell[x]; - let existingWidth = result[col]; - let editableCols = typeof vals[col] === 'number' ? 0 : 1; - 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) { - if (typeof vals[col + i] !== 'number') { - let dif = Math.round((cell[desiredWidth] - existingWidth) / editableCols); - existingWidth += dif; - result[col + i] += dif; - editableCols--; - } - i++; - } - } - } - - Object.assign(vals, result, auto); - for (let j = 0; j < vals.length; j++) { - vals[j] = Math.max(forcedMin, vals[j] || 0); - } - }; -} diff --git a/deps/npm/node_modules/cli-table3/src/table.js b/deps/npm/node_modules/cli-table3/src/table.js deleted file mode 100644 index eb4a9bda9a3649..00000000000000 --- a/deps/npm/node_modules/cli-table3/src/table.js +++ /dev/null @@ -1,106 +0,0 @@ -const debug = require('./debug'); -const utils = require('./utils'); -const tableLayout = require('./layout-manager'); - -class Table extends Array { - constructor(opts) { - super(); - - 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() { - let array = this; - let headersPresent = this.options.head && this.options.head.length; - if (headersPresent) { - array = [this.options.head]; - if (this.length) { - array.push.apply(array, this); - } - } else { - this.options.style.head = []; - } - - let cells = tableLayout.makeTableLayout(array); - - cells.forEach(function (row) { - row.forEach(function (cell) { - cell.mergeTableOptions(this.options, cells); - }, this); - }, this); - - tableLayout.computeWidths(this.options.colWidths, cells); - tableLayout.computeHeights(this.options.rowHeights, cells); - - cells.forEach(function (row) { - row.forEach(function (cell) { - cell.init(this.options); - }, this); - }, this); - - let result = []; - - for (let rowIndex = 0; rowIndex < cells.length; rowIndex++) { - let row = cells[rowIndex]; - let heightOfRow = this.options.rowHeights[rowIndex]; - - if (rowIndex === 0 || !this.options.style.compact || (rowIndex == 1 && headersPresent)) { - doDraw(row, 'top', result); - } - - for (let lineNum = 0; lineNum < heightOfRow; lineNum++) { - doDraw(row, lineNum, result); - } - - if (rowIndex + 1 == cells.length) { - doDraw(row, 'bottom', result); - } - } - - return result.join('\n'); - } - - get width() { - let str = this.toString().split('\n'); - return str[0].length; - } -} - -Table.reset = () => debug.reset(); - -function doDraw(row, lineNum, result) { - let line = []; - row.forEach(function (cell) { - line.push(cell.draw(lineNum)); - }); - let str = line.join(''); - if (str.length) result.push(str); -} - -module.exports = Table; diff --git a/deps/npm/node_modules/cli-table3/src/utils.js b/deps/npm/node_modules/cli-table3/src/utils.js deleted file mode 100644 index c922c5b9adb62c..00000000000000 --- a/deps/npm/node_modules/cli-table3/src/utils.js +++ /dev/null @@ -1,336 +0,0 @@ -const stringWidth = require('string-width'); - -function codeRegex(capture) { - return capture ? /\u001b\[((?:\d*;){0,5}\d*)m/g : /\u001b\[(?:\d*;){0,5}\d*m/g; -} - -function strlen(str) { - let code = codeRegex(); - let stripped = ('' + str).replace(code, ''); - let split = stripped.split('\n'); - return split.reduce(function (memo, s) { - return stringWidth(s) > memo ? stringWidth(s) : memo; - }, 0); -} - -function repeat(str, times) { - return Array(times + 1).join(str); -} - -function pad(str, len, pad, dir) { - let length = strlen(str); - if (len + 1 >= length) { - let padlen = len - length; - switch (dir) { - case 'right': { - str = repeat(pad, padlen) + str; - break; - } - case 'center': { - let right = Math.ceil(padlen / 2); - let left = padlen - right; - str = repeat(pad, left) + str + repeat(pad, right); - break; - } - default: { - str = str + repeat(pad, padlen); - break; - } - } - } - return str; -} - -let codeCache = {}; - -function addToCodeCache(name, on, off) { - on = '\u001b[' + on + 'm'; - off = '\u001b[' + off + 'm'; - codeCache[on] = { set: name, to: true }; - codeCache[off] = { set: name, to: false }; - codeCache[name] = { on: on, off: off }; -} - -//https://github.com/Marak/colors.js/blob/master/lib/styles.js -addToCodeCache('bold', 1, 22); -addToCodeCache('italics', 3, 23); -addToCodeCache('underline', 4, 24); -addToCodeCache('inverse', 7, 27); -addToCodeCache('strikethrough', 9, 29); - -function updateState(state, controlChars) { - let controlCode = controlChars[1] ? parseInt(controlChars[1].split(';')[0]) : 0; - if ((controlCode >= 30 && controlCode <= 39) || (controlCode >= 90 && controlCode <= 97)) { - state.lastForegroundAdded = controlChars[0]; - return; - } - if ((controlCode >= 40 && controlCode <= 49) || (controlCode >= 100 && controlCode <= 107)) { - state.lastBackgroundAdded = controlChars[0]; - return; - } - if (controlCode === 0) { - for (let i in state) { - /* istanbul ignore else */ - if (Object.prototype.hasOwnProperty.call(state, i)) { - delete state[i]; - } - } - return; - } - let info = codeCache[controlChars[0]]; - if (info) { - state[info.set] = info.to; - } -} - -function readState(line) { - let code = codeRegex(true); - let controlChars = code.exec(line); - let state = {}; - while (controlChars !== null) { - updateState(state, controlChars); - controlChars = code.exec(line); - } - return state; -} - -function unwindState(state, ret) { - let lastBackgroundAdded = state.lastBackgroundAdded; - let lastForegroundAdded = state.lastForegroundAdded; - - delete state.lastBackgroundAdded; - delete state.lastForegroundAdded; - - Object.keys(state).forEach(function (key) { - if (state[key]) { - ret += codeCache[key].off; - } - }); - - if (lastBackgroundAdded && lastBackgroundAdded != '\u001b[49m') { - ret += '\u001b[49m'; - } - if (lastForegroundAdded && lastForegroundAdded != '\u001b[39m') { - ret += '\u001b[39m'; - } - - return ret; -} - -function rewindState(state, ret) { - let lastBackgroundAdded = state.lastBackgroundAdded; - let lastForegroundAdded = state.lastForegroundAdded; - - delete state.lastBackgroundAdded; - delete state.lastForegroundAdded; - - Object.keys(state).forEach(function (key) { - if (state[key]) { - ret = codeCache[key].on + ret; - } - }); - - if (lastBackgroundAdded && lastBackgroundAdded != '\u001b[49m') { - ret = lastBackgroundAdded + ret; - } - if (lastForegroundAdded && lastForegroundAdded != '\u001b[39m') { - ret = lastForegroundAdded + ret; - } - - return ret; -} - -function truncateWidth(str, desiredLength) { - if (str.length === strlen(str)) { - return str.substr(0, desiredLength); - } - - while (strlen(str) > desiredLength) { - str = str.slice(0, -1); - } - - return str; -} - -function truncateWidthWithAnsi(str, desiredLength) { - let code = codeRegex(true); - let split = str.split(codeRegex()); - let splitIndex = 0; - let retLen = 0; - let ret = ''; - let myArray; - let state = {}; - - while (retLen < desiredLength) { - myArray = code.exec(str); - let toAdd = split[splitIndex]; - splitIndex++; - if (retLen + strlen(toAdd) > desiredLength) { - toAdd = truncateWidth(toAdd, desiredLength - retLen); - } - ret += toAdd; - retLen += strlen(toAdd); - - if (retLen < desiredLength) { - if (!myArray) { - break; - } // full-width chars may cause a whitespace which cannot be filled - ret += myArray[0]; - updateState(state, myArray); - } - } - - return unwindState(state, ret); -} - -function truncate(str, desiredLength, truncateChar) { - truncateChar = truncateChar || '…'; - let lengthOfStr = strlen(str); - if (lengthOfStr <= desiredLength) { - return str; - } - desiredLength -= strlen(truncateChar); - - let ret = truncateWidthWithAnsi(str, desiredLength); - - return ret + truncateChar; -} - -function defaultOptions() { - return { - chars: { - top: '─', - 'top-mid': '┬', - 'top-left': '┌', - 'top-right': '┐', - bottom: '─', - 'bottom-mid': '┴', - 'bottom-left': '└', - 'bottom-right': '┘', - left: '│', - 'left-mid': '├', - mid: '─', - 'mid-mid': '┼', - right: '│', - 'right-mid': '┤', - middle: '│', - }, - truncate: '…', - colWidths: [], - rowHeights: [], - colAligns: [], - rowAligns: [], - style: { - 'padding-left': 1, - 'padding-right': 1, - head: ['red'], - border: ['grey'], - compact: false, - }, - head: [], - }; -} - -function mergeOptions(options, defaults) { - options = options || {}; - defaults = defaults || defaultOptions(); - let ret = Object.assign({}, defaults, options); - ret.chars = Object.assign({}, defaults.chars, options.chars); - ret.style = Object.assign({}, defaults.style, options.style); - return ret; -} - -// Wrap on word boundary -function wordWrap(maxLength, input) { - let lines = []; - let split = input.split(/(\s+)/g); - let line = []; - let lineLength = 0; - let whitespace; - for (let i = 0; i < split.length; i += 2) { - let word = split[i]; - let newLength = lineLength + strlen(word); - if (lineLength > 0 && whitespace) { - newLength += whitespace.length; - } - if (newLength > maxLength) { - if (lineLength !== 0) { - lines.push(line.join('')); - } - line = [word]; - lineLength = strlen(word); - } else { - line.push(whitespace || '', word); - lineLength = newLength; - } - whitespace = split[i + 1]; - } - if (lineLength) { - lines.push(line.join('')); - } - return lines; -} - -// 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, handler(maxLength, input[i])); - } - return output; -} - -function colorizeLines(input) { - let state = {}; - let output = []; - for (let i = 0; i < input.length; i++) { - let line = rewindState(state, input[i]); - state = readState(line); - let temp = Object.assign({}, state); - output.push(unwindState(temp, line)); - } - 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, - pad: pad, - truncate: truncate, - mergeOptions: mergeOptions, - wordWrap: multiLineWordWrap, - colorizeLines: colorizeLines, - hyperlink, -}; diff --git a/deps/npm/node_modules/clone/LICENSE b/deps/npm/node_modules/clone/LICENSE deleted file mode 100644 index cc3c87bc3bfd85..00000000000000 --- a/deps/npm/node_modules/clone/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -Copyright © 2011-2015 Paul Vorbach - -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, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/deps/npm/node_modules/clone/clone.iml b/deps/npm/node_modules/clone/clone.iml deleted file mode 100644 index 30de8aee9ba303..00000000000000 --- a/deps/npm/node_modules/clone/clone.iml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/deps/npm/node_modules/clone/clone.js b/deps/npm/node_modules/clone/clone.js deleted file mode 100644 index ba200c2f99288d..00000000000000 --- a/deps/npm/node_modules/clone/clone.js +++ /dev/null @@ -1,166 +0,0 @@ -var clone = (function() { -'use strict'; - -/** - * Clones (copies) an Object using deep copying. - * - * This function supports circular references by default, but if you are certain - * there are no circular references in your object, you can save some CPU time - * by calling clone(obj, false). - * - * Caution: if `circular` is false and `parent` contains circular references, - * your program may enter an infinite loop and crash. - * - * @param `parent` - the object to be cloned - * @param `circular` - set to true if the object to be cloned may contain - * circular references. (optional - true by default) - * @param `depth` - set to a number if the object is only to be cloned to - * a particular depth. (optional - defaults to Infinity) - * @param `prototype` - sets the prototype to be used when cloning an object. - * (optional - defaults to parent prototype). -*/ -function clone(parent, circular, depth, prototype) { - var filter; - if (typeof circular === 'object') { - depth = circular.depth; - prototype = circular.prototype; - filter = circular.filter; - circular = circular.circular - } - // maintain two arrays for circular references, where corresponding parents - // and children have the same index - var allParents = []; - var allChildren = []; - - var useBuffer = typeof Buffer != 'undefined'; - - if (typeof circular == 'undefined') - circular = true; - - if (typeof depth == 'undefined') - depth = Infinity; - - // recurse this function so we don't reset allParents and allChildren - function _clone(parent, depth) { - // cloning null always returns null - if (parent === null) - return null; - - if (depth == 0) - return parent; - - var child; - var proto; - if (typeof parent != 'object') { - return parent; - } - - if (clone.__isArray(parent)) { - child = []; - } else if (clone.__isRegExp(parent)) { - child = new RegExp(parent.source, __getRegExpFlags(parent)); - if (parent.lastIndex) child.lastIndex = parent.lastIndex; - } else if (clone.__isDate(parent)) { - child = new Date(parent.getTime()); - } else if (useBuffer && Buffer.isBuffer(parent)) { - if (Buffer.allocUnsafe) { - // Node.js >= 4.5.0 - child = Buffer.allocUnsafe(parent.length); - } else { - // Older Node.js versions - child = new Buffer(parent.length); - } - parent.copy(child); - return child; - } else { - if (typeof prototype == 'undefined') { - proto = Object.getPrototypeOf(parent); - child = Object.create(proto); - } - else { - child = Object.create(prototype); - proto = prototype; - } - } - - if (circular) { - var index = allParents.indexOf(parent); - - if (index != -1) { - return allChildren[index]; - } - allParents.push(parent); - allChildren.push(child); - } - - for (var i in parent) { - var attrs; - if (proto) { - attrs = Object.getOwnPropertyDescriptor(proto, i); - } - - if (attrs && attrs.set == null) { - continue; - } - child[i] = _clone(parent[i], depth - 1); - } - - return child; - } - - return _clone(parent, depth); -} - -/** - * Simple flat clone using prototype, accepts only objects, usefull for property - * override on FLAT configuration object (no nested props). - * - * USE WITH CAUTION! This may not behave as you wish if you do not know how this - * works. - */ -clone.clonePrototype = function clonePrototype(parent) { - if (parent === null) - return null; - - var c = function () {}; - c.prototype = parent; - return new c(); -}; - -// private utility functions - -function __objToStr(o) { - return Object.prototype.toString.call(o); -}; -clone.__objToStr = __objToStr; - -function __isDate(o) { - return typeof o === 'object' && __objToStr(o) === '[object Date]'; -}; -clone.__isDate = __isDate; - -function __isArray(o) { - return typeof o === 'object' && __objToStr(o) === '[object Array]'; -}; -clone.__isArray = __isArray; - -function __isRegExp(o) { - return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; -}; -clone.__isRegExp = __isRegExp; - -function __getRegExpFlags(re) { - var flags = ''; - if (re.global) flags += 'g'; - if (re.ignoreCase) flags += 'i'; - if (re.multiline) flags += 'm'; - return flags; -}; -clone.__getRegExpFlags = __getRegExpFlags; - -return clone; -})(); - -if (typeof module === 'object' && module.exports) { - module.exports = clone; -} diff --git a/deps/npm/node_modules/clone/package.json b/deps/npm/node_modules/clone/package.json deleted file mode 100644 index 3ddd242f4a5108..00000000000000 --- a/deps/npm/node_modules/clone/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "clone", - "description": "deep cloning of objects and arrays", - "tags": [ - "clone", - "object", - "array", - "function", - "date" - ], - "version": "1.0.4", - "repository": { - "type": "git", - "url": "git://github.com/pvorb/node-clone.git" - }, - "bugs": { - "url": "https://github.com/pvorb/node-clone/issues" - }, - "main": "clone.js", - "author": "Paul Vorbach (http://paul.vorba.ch/)", - "contributors": [ - "Blake Miner (http://www.blakeminer.com/)", - "Tian You (http://blog.axqd.net/)", - "George Stagas (http://stagas.com/)", - "Tobiasz Cudnik (https://github.com/TobiaszCudnik)", - "Pavel Lang (https://github.com/langpavel)", - "Dan MacTough (http://yabfog.com/)", - "w1nk (https://github.com/w1nk)", - "Hugh Kennedy (http://twitter.com/hughskennedy)", - "Dustin Diaz (http://dustindiaz.com)", - "Ilya Shaisultanov (https://github.com/diversario)", - "Nathan MacInnes (http://macinn.es/)", - "Benjamin E. Coe (https://twitter.com/benjamincoe)", - "Nathan Zadoks (https://github.com/nathan7)", - "Róbert Oroszi (https://github.com/oroce)", - "Aurélio A. Heckert (http://softwarelivre.org/aurium)", - "Guy Ellis (http://www.guyellisrocks.com/)" - ], - "license": "MIT", - "engines": { - "node": ">=0.8" - }, - "dependencies": {}, - "devDependencies": { - "nodeunit": "~0.9.0" - }, - "optionalDependencies": {}, - "scripts": { - "test": "nodeunit test.js" - } -} diff --git a/deps/npm/node_modules/color-support/README.md b/deps/npm/node_modules/color-support/README.md deleted file mode 100644 index f89aa17d3526a3..00000000000000 --- a/deps/npm/node_modules/color-support/README.md +++ /dev/null @@ -1,129 +0,0 @@ -# color-support - -A module which will endeavor to guess your terminal's level of color -support. - -[![Build Status](https://travis-ci.org/isaacs/color-support.svg?branch=master)](https://travis-ci.org/isaacs/color-support) [![Coverage Status](https://coveralls.io/repos/github/isaacs/color-support/badge.svg?branch=master)](https://coveralls.io/github/isaacs/color-support?branch=master) - -This is similar to `supports-color`, but it does not read -`process.argv`. - -1. If not in a node environment, not supported. - -2. If stdout is not a TTY, not supported, unless the `ignoreTTY` - option is set. - -3. If the `TERM` environ is `dumb`, not supported, unless the - `ignoreDumb` option is set. - -4. If on Windows, then support 16 colors. - -5. If using Tmux, then support 256 colors. - -7. Handle continuous-integration servers. If `CI` or - `TEAMCITY_VERSION` are set in the environment, and `TRAVIS` is not - set, then color is not supported, unless `ignoreCI` option is set. - -6. Guess based on the `TERM_PROGRAM` environ. These terminals support - 16m colors: - - - `iTerm.app` version 3.x supports 16m colors, below support 256 - - `MacTerm` supports 16m colors - - `Apple_Terminal` supports 256 colors - - Have more things that belong on this list? Send a PR! - -8. Make a guess based on the `TERM` environment variable. Any - `xterm-256color` will get 256 colors. Any screen, xterm, vt100, - color, ansi, cygwin, or linux `TERM` will get 16 colors. - -9. If `COLORTERM` environment variable is set, then support 16 colors. - -10. At this point, we assume that color is not supported. - -## USAGE - -```javascript -var testColorSupport = require('color-support') -var colorSupport = testColorSupport(/* options object */) - -if (!colorSupport) { - console.log('color is not supported') -} else if (colorSupport.has16m) { - console.log('\x1b[38;2;102;194;255m16m colors\x1b[0m') -} else if (colorSupport.has256) { - console.log('\x1b[38;5;119m256 colors\x1b[0m') -} else if (colorSupport.hasBasic) { - console.log('\x1b[31mbasic colors\x1b[0m') -} else { - console.log('this is impossible, but colors are not supported') -} -``` - -If you don't have any options to set, you can also just look at the -flags which will all be set on the test function itself. (Of course, -this doesn't return a falsey value when colors aren't supported, and -doesn't allow you to set options.) - -```javascript -var colorSupport = require('color-support') - -if (colorSupport.has16m) { - console.log('\x1b[38;2;102;194;255m16m colors\x1b[0m') -} else if (colorSupport.has256) { - console.log('\x1b[38;5;119m256 colors\x1b[0m') -} else if (colorSupport.hasBasic) { - console.log('\x1b[31mbasic colors\x1b[0m') -} else { - console.log('colors are not supported') -} -``` - -## Options - -You can pass in the following options. - -* ignoreTTY - default false. Ignore the `isTTY` check. -* ignoreDumb - default false. Ignore `TERM=dumb` environ check. -* ignoreCI - default false. Ignore `CI` environ check. -* env - Object for environment vars. Defaults to `process.env`. -* stream - Stream for `isTTY` check. Defaults to `process.stdout`. -* term - String for `TERM` checking. Defaults to `env.TERM`. -* alwaysReturn - default false. Return an object when colors aren't - supported (instead of returning `false`). -* level - A number from 0 to 3. This will return a result for the - specified level. This is useful if you want to be able to set the - color support level explicitly as a number in an environment - variable or config, but then use the object flags in your program. - Except for `alwaysReturn` to return an object for level 0, all other - options are ignored, since no checking is done if a level is - explicitly set. - -## Return Value - -If no color support is available, then `false` is returned by default, -unless the `alwaysReturn` flag is set to `true`. This is so that the -simple question of "can I use colors or not" can treat any truthy -return as "yes". - -Otherwise, the return object has the following fields: - -* `level` - A number from 0 to 3 - * `0` - No color support - * `1` - Basic (16) color support - * `2` - 256 color support - * `3` - 16 million (true) color support -* `hasBasic` - Boolean -* `has256` - Boolean -* `has16m` - Boolean - -## CLI - -You can run the `color-support` bin from the command line which will -just dump the values as this module calculates them in whatever env -it's run. It takes no command line arguments. - -## Credits - -This is a spiritual, if not actual, fork of -[supports-color](http://npm.im/supports-color) by the ever prolific -[Sindre Sorhus](http://npm.im/~sindresorhus). diff --git a/deps/npm/node_modules/color-support/bin.js b/deps/npm/node_modules/color-support/bin.js deleted file mode 100755 index 3c0a9672180835..00000000000000 --- a/deps/npm/node_modules/color-support/bin.js +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node -var colorSupport = require('./')({alwaysReturn: true }) -console.log(JSON.stringify(colorSupport, null, 2)) diff --git a/deps/npm/node_modules/color-support/browser.js b/deps/npm/node_modules/color-support/browser.js deleted file mode 100644 index ab5c6631a35b80..00000000000000 --- a/deps/npm/node_modules/color-support/browser.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = colorSupport({ alwaysReturn: true }, colorSupport) - -function colorSupport(options, obj) { - obj = obj || {} - options = options || {} - obj.level = 0 - obj.hasBasic = false - obj.has256 = false - obj.has16m = false - if (!options.alwaysReturn) { - return false - } - return obj -} diff --git a/deps/npm/node_modules/color-support/index.js b/deps/npm/node_modules/color-support/index.js deleted file mode 100644 index 6b6f3b28194243..00000000000000 --- a/deps/npm/node_modules/color-support/index.js +++ /dev/null @@ -1,134 +0,0 @@ -// call it on itself so we can test the export val for basic stuff -module.exports = colorSupport({ alwaysReturn: true }, colorSupport) - -function hasNone (obj, options) { - obj.level = 0 - obj.hasBasic = false - obj.has256 = false - obj.has16m = false - if (!options.alwaysReturn) { - return false - } - return obj -} - -function hasBasic (obj) { - obj.hasBasic = true - obj.has256 = false - obj.has16m = false - obj.level = 1 - return obj -} - -function has256 (obj) { - obj.hasBasic = true - obj.has256 = true - obj.has16m = false - obj.level = 2 - return obj -} - -function has16m (obj) { - obj.hasBasic = true - obj.has256 = true - obj.has16m = true - obj.level = 3 - return obj -} - -function colorSupport (options, obj) { - options = options || {} - - obj = obj || {} - - // if just requesting a specific level, then return that. - if (typeof options.level === 'number') { - switch (options.level) { - case 0: - return hasNone(obj, options) - case 1: - return hasBasic(obj) - case 2: - return has256(obj) - case 3: - return has16m(obj) - } - } - - obj.level = 0 - obj.hasBasic = false - obj.has256 = false - obj.has16m = false - - if (typeof process === 'undefined' || - !process || - !process.stdout || - !process.env || - !process.platform) { - return hasNone(obj, options) - } - - var env = options.env || process.env - var stream = options.stream || process.stdout - var term = options.term || env.TERM || '' - var platform = options.platform || process.platform - - if (!options.ignoreTTY && !stream.isTTY) { - return hasNone(obj, options) - } - - if (!options.ignoreDumb && term === 'dumb' && !env.COLORTERM) { - return hasNone(obj, options) - } - - if (platform === 'win32') { - return hasBasic(obj) - } - - if (env.TMUX) { - return has256(obj) - } - - if (!options.ignoreCI && (env.CI || env.TEAMCITY_VERSION)) { - if (env.TRAVIS) { - return has256(obj) - } else { - return hasNone(obj, options) - } - } - - // TODO: add more term programs - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - var ver = env.TERM_PROGRAM_VERSION || '0.' - if (/^[0-2]\./.test(ver)) { - return has256(obj) - } else { - return has16m(obj) - } - - case 'HyperTerm': - case 'Hyper': - return has16m(obj) - - case 'MacTerm': - return has16m(obj) - - case 'Apple_Terminal': - return has256(obj) - } - - if (/^xterm-256/.test(term)) { - return has256(obj) - } - - if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(term)) { - return hasBasic(obj) - } - - if (env.COLORTERM) { - return hasBasic(obj) - } - - return hasNone(obj, options) -} diff --git a/deps/npm/node_modules/color-support/package.json b/deps/npm/node_modules/color-support/package.json deleted file mode 100644 index f3e3b77145d6ba..00000000000000 --- a/deps/npm/node_modules/color-support/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "color-support", - "version": "1.1.3", - "description": "A module which will endeavor to guess your terminal's level of color support.", - "main": "index.js", - "browser": "browser.js", - "bin": "bin.js", - "devDependencies": { - "tap": "^10.3.3" - }, - "scripts": { - "test": "tap test/*.js --100 -J", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/isaacs/color-support.git" - }, - "keywords": [ - "terminal", - "color", - "support", - "xterm", - "truecolor", - "256" - ], - "author": "Isaac Z. Schlueter (http://blog.izs.me/)", - "license": "ISC", - "files": [ - "browser.js", - "index.js", - "bin.js" - ] -} diff --git a/deps/npm/node_modules/columnify/LICENSE b/deps/npm/node_modules/columnify/LICENSE deleted file mode 100644 index ed47678e61c408..00000000000000 --- a/deps/npm/node_modules/columnify/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 Tim Oxley - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/deps/npm/node_modules/columnify/Makefile b/deps/npm/node_modules/columnify/Makefile deleted file mode 100644 index 3a67c57a3b1e08..00000000000000 --- a/deps/npm/node_modules/columnify/Makefile +++ /dev/null @@ -1,9 +0,0 @@ - -all: columnify.js - -prepublish: all - -columnify.js: index.js package.json - babel index.js > columnify.js - -.PHONY: all prepublish diff --git a/deps/npm/node_modules/columnify/columnify.js b/deps/npm/node_modules/columnify/columnify.js deleted file mode 100644 index dcef9236e18436..00000000000000 --- a/deps/npm/node_modules/columnify/columnify.js +++ /dev/null @@ -1,306 +0,0 @@ -"use strict"; - -var wcwidth = require('./width'); - -var _require = require('./utils'), - padRight = _require.padRight, - padCenter = _require.padCenter, - padLeft = _require.padLeft, - splitIntoLines = _require.splitIntoLines, - splitLongWords = _require.splitLongWords, - truncateString = _require.truncateString; - -var DEFAULT_HEADING_TRANSFORM = function DEFAULT_HEADING_TRANSFORM(key) { - return key.toUpperCase(); -}; - -var DEFAULT_DATA_TRANSFORM = function DEFAULT_DATA_TRANSFORM(cell, column, index) { - return cell; -}; - -var DEFAULTS = Object.freeze({ - maxWidth: Infinity, - minWidth: 0, - columnSplitter: ' ', - truncate: false, - truncateMarker: '…', - preserveNewLines: false, - paddingChr: ' ', - showHeaders: true, - headingTransform: DEFAULT_HEADING_TRANSFORM, - dataTransform: DEFAULT_DATA_TRANSFORM -}); - -module.exports = function (items) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - - var columnConfigs = options.config || {}; - delete options.config; // remove config so doesn't appear on every column. - - var maxLineWidth = options.maxLineWidth || Infinity; - if (maxLineWidth === 'auto') maxLineWidth = process.stdout.columns || Infinity; - delete options.maxLineWidth; // this is a line control option, don't pass it to column - - // Option defaults inheritance: - // options.config[columnName] => options => DEFAULTS - options = mixin({}, DEFAULTS, options); - - options.config = options.config || Object.create(null); - - options.spacing = options.spacing || '\n'; // probably useless - options.preserveNewLines = !!options.preserveNewLines; - options.showHeaders = !!options.showHeaders; - options.columns = options.columns || options.include; // alias include/columns, prefer columns if supplied - var columnNames = options.columns || []; // optional user-supplied columns to include - - items = toArray(items, columnNames); - - // if not suppled column names, automatically determine columns from data keys - if (!columnNames.length) { - items.forEach(function (item) { - for (var columnName in item) { - if (columnNames.indexOf(columnName) === -1) columnNames.push(columnName); - } - }); - } - - // initialize column defaults (each column inherits from options.config) - var columns = columnNames.reduce(function (columns, columnName) { - var column = Object.create(options); - columns[columnName] = mixin(column, columnConfigs[columnName]); - return columns; - }, Object.create(null)); - - // sanitize column settings - columnNames.forEach(function (columnName) { - var column = columns[columnName]; - column.name = columnName; - column.maxWidth = Math.ceil(column.maxWidth); - column.minWidth = Math.ceil(column.minWidth); - column.truncate = !!column.truncate; - column.align = column.align || 'left'; - }); - - // sanitize data - items = items.map(function (item) { - var result = Object.create(null); - columnNames.forEach(function (columnName) { - // null/undefined -> '' - result[columnName] = item[columnName] != null ? item[columnName] : ''; - // toString everything - result[columnName] = '' + result[columnName]; - if (columns[columnName].preserveNewLines) { - // merge non-newline whitespace chars - result[columnName] = result[columnName].replace(/[^\S\n]/gmi, ' '); - } else { - // merge all whitespace chars - result[columnName] = result[columnName].replace(/\s/gmi, ' '); - } - }); - return result; - }); - - // transform data cells - columnNames.forEach(function (columnName) { - var column = columns[columnName]; - items = items.map(function (item, index) { - var col = Object.create(column); - item[columnName] = column.dataTransform(item[columnName], col, index); - - var changedKeys = Object.keys(col); - // disable default heading transform if we wrote to column.name - if (changedKeys.indexOf('name') !== -1) { - if (column.headingTransform !== DEFAULT_HEADING_TRANSFORM) return; - column.headingTransform = function (heading) { - return heading; - }; - } - changedKeys.forEach(function (key) { - return column[key] = col[key]; - }); - return item; - }); - }); - - // add headers - var headers = {}; - if (options.showHeaders) { - columnNames.forEach(function (columnName) { - var column = columns[columnName]; - - if (!column.showHeaders) { - headers[columnName] = ''; - return; - } - - headers[columnName] = column.headingTransform(column.name); - }); - items.unshift(headers); - } - // get actual max-width between min & max - // based on length of data in columns - columnNames.forEach(function (columnName) { - var column = columns[columnName]; - column.width = items.map(function (item) { - return item[columnName]; - }).reduce(function (min, cur) { - // if already at maxWidth don't bother testing - if (min >= column.maxWidth) return min; - return Math.max(min, Math.min(column.maxWidth, Math.max(column.minWidth, wcwidth(cur)))); - }, 0); - }); - - // split long words so they can break onto multiple lines - columnNames.forEach(function (columnName) { - var column = columns[columnName]; - items = items.map(function (item) { - item[columnName] = splitLongWords(item[columnName], column.width, column.truncateMarker); - return item; - }); - }); - - // wrap long lines. each item is now an array of lines. - columnNames.forEach(function (columnName) { - var column = columns[columnName]; - items = items.map(function (item, index) { - var cell = item[columnName]; - item[columnName] = splitIntoLines(cell, column.width); - - // if truncating required, only include first line + add truncation char - if (column.truncate && item[columnName].length > 1) { - item[columnName] = splitIntoLines(cell, column.width - wcwidth(column.truncateMarker)); - var firstLine = item[columnName][0]; - if (!endsWith(firstLine, column.truncateMarker)) item[columnName][0] += column.truncateMarker; - item[columnName] = item[columnName].slice(0, 1); - } - return item; - }); - }); - - // recalculate column widths from truncated output/lines - columnNames.forEach(function (columnName) { - var column = columns[columnName]; - column.width = items.map(function (item) { - return item[columnName].reduce(function (min, cur) { - if (min >= column.maxWidth) return min; - return Math.max(min, Math.min(column.maxWidth, Math.max(column.minWidth, wcwidth(cur)))); - }, 0); - }).reduce(function (min, cur) { - if (min >= column.maxWidth) return min; - return Math.max(min, Math.min(column.maxWidth, Math.max(column.minWidth, cur))); - }, 0); - }); - - var rows = createRows(items, columns, columnNames, options.paddingChr); // merge lines into rows - // conceive output - return rows.reduce(function (output, row) { - return output.concat(row.reduce(function (rowOut, line) { - return rowOut.concat(line.join(options.columnSplitter)); - }, [])); - }, []).map(function (line) { - return truncateString(line, maxLineWidth); - }).join(options.spacing); -}; - -/** - * Convert wrapped lines into rows with padded values. - * - * @param Array items data to process - * @param Array columns column width settings for wrapping - * @param Array columnNames column ordering - * @return Array items wrapped in arrays, corresponding to lines - */ - -function createRows(items, columns, columnNames, paddingChr) { - return items.map(function (item) { - var row = []; - var numLines = 0; - columnNames.forEach(function (columnName) { - numLines = Math.max(numLines, item[columnName].length); - }); - // combine matching lines of each rows - - var _loop = function _loop(i) { - row[i] = row[i] || []; - columnNames.forEach(function (columnName) { - var column = columns[columnName]; - var val = item[columnName][i] || ''; // || '' ensures empty columns get padded - if (column.align === 'right') row[i].push(padLeft(val, column.width, paddingChr));else if (column.align === 'center' || column.align === 'centre') row[i].push(padCenter(val, column.width, paddingChr));else row[i].push(padRight(val, column.width, paddingChr)); - }); - }; - - for (var i = 0; i < numLines; i++) { - _loop(i); - } - return row; - }); -} - -/** - * Object.assign - * - * @return Object Object with properties mixed in. - */ - -function mixin() { - if (Object.assign) return Object.assign.apply(Object, arguments); - return ObjectAssign.apply(undefined, arguments); -} - -function ObjectAssign(target, firstSource) { - "use strict"; - - if (target === undefined || target === null) throw new TypeError("Cannot convert first argument to object"); - - var to = Object(target); - - var hasPendingException = false; - var pendingException; - - for (var i = 1; i < arguments.length; i++) { - var nextSource = arguments[i]; - if (nextSource === undefined || nextSource === null) continue; - - var keysArray = Object.keys(Object(nextSource)); - for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) { - var nextKey = keysArray[nextIndex]; - try { - var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey); - if (desc !== undefined && desc.enumerable) to[nextKey] = nextSource[nextKey]; - } catch (e) { - if (!hasPendingException) { - hasPendingException = true; - pendingException = e; - } - } - } - - if (hasPendingException) throw pendingException; - } - return to; -} - -/** - * Adapted from String.prototype.endsWith polyfill. - */ - -function endsWith(target, searchString, position) { - position = position || target.length; - position = position - searchString.length; - var lastIndex = target.lastIndexOf(searchString); - return lastIndex !== -1 && lastIndex === position; -} - -function toArray(items, columnNames) { - if (Array.isArray(items)) return items; - var rows = []; - for (var key in items) { - var item = {}; - item[columnNames[0] || 'key'] = key; - item[columnNames[1] || 'value'] = items[key]; - rows.push(item); - } - return rows; -} - diff --git a/deps/npm/node_modules/columnify/index.js b/deps/npm/node_modules/columnify/index.js deleted file mode 100644 index 221269b3e76b72..00000000000000 --- a/deps/npm/node_modules/columnify/index.js +++ /dev/null @@ -1,297 +0,0 @@ -"use strict" - -const wcwidth = require('./width') -const { - padRight, - padCenter, - padLeft, - splitIntoLines, - splitLongWords, - truncateString -} = require('./utils') - -const DEFAULT_HEADING_TRANSFORM = key => key.toUpperCase() - -const DEFAULT_DATA_TRANSFORM = (cell, column, index) => cell - -const DEFAULTS = Object.freeze({ - maxWidth: Infinity, - minWidth: 0, - columnSplitter: ' ', - truncate: false, - truncateMarker: '…', - preserveNewLines: false, - paddingChr: ' ', - showHeaders: true, - headingTransform: DEFAULT_HEADING_TRANSFORM, - dataTransform: DEFAULT_DATA_TRANSFORM -}) - -module.exports = function(items, options = {}) { - - let columnConfigs = options.config || {} - delete options.config // remove config so doesn't appear on every column. - - let maxLineWidth = options.maxLineWidth || Infinity - if (maxLineWidth === 'auto') maxLineWidth = process.stdout.columns || Infinity - delete options.maxLineWidth // this is a line control option, don't pass it to column - - // Option defaults inheritance: - // options.config[columnName] => options => DEFAULTS - options = mixin({}, DEFAULTS, options) - - options.config = options.config || Object.create(null) - - options.spacing = options.spacing || '\n' // probably useless - options.preserveNewLines = !!options.preserveNewLines - options.showHeaders = !!options.showHeaders; - options.columns = options.columns || options.include // alias include/columns, prefer columns if supplied - let columnNames = options.columns || [] // optional user-supplied columns to include - - items = toArray(items, columnNames) - - // if not suppled column names, automatically determine columns from data keys - if (!columnNames.length) { - items.forEach(function(item) { - for (let columnName in item) { - if (columnNames.indexOf(columnName) === -1) columnNames.push(columnName) - } - }) - } - - // initialize column defaults (each column inherits from options.config) - let columns = columnNames.reduce((columns, columnName) => { - let column = Object.create(options) - columns[columnName] = mixin(column, columnConfigs[columnName]) - return columns - }, Object.create(null)) - - // sanitize column settings - columnNames.forEach(columnName => { - let column = columns[columnName] - column.name = columnName - column.maxWidth = Math.ceil(column.maxWidth) - column.minWidth = Math.ceil(column.minWidth) - column.truncate = !!column.truncate - column.align = column.align || 'left' - }) - - // sanitize data - items = items.map(item => { - let result = Object.create(null) - columnNames.forEach(columnName => { - // null/undefined -> '' - result[columnName] = item[columnName] != null ? item[columnName] : '' - // toString everything - result[columnName] = '' + result[columnName] - if (columns[columnName].preserveNewLines) { - // merge non-newline whitespace chars - result[columnName] = result[columnName].replace(/[^\S\n]/gmi, ' ') - } else { - // merge all whitespace chars - result[columnName] = result[columnName].replace(/\s/gmi, ' ') - } - }) - return result - }) - - // transform data cells - columnNames.forEach(columnName => { - let column = columns[columnName] - items = items.map((item, index) => { - let col = Object.create(column) - item[columnName] = column.dataTransform(item[columnName], col, index) - - let changedKeys = Object.keys(col) - // disable default heading transform if we wrote to column.name - if (changedKeys.indexOf('name') !== -1) { - if (column.headingTransform !== DEFAULT_HEADING_TRANSFORM) return - column.headingTransform = heading => heading - } - changedKeys.forEach(key => column[key] = col[key]) - return item - }) - }) - - // add headers - let headers = {} - if(options.showHeaders) { - columnNames.forEach(columnName => { - let column = columns[columnName] - - if(!column.showHeaders){ - headers[columnName] = ''; - return; - } - - headers[columnName] = column.headingTransform(column.name) - }) - items.unshift(headers) - } - // get actual max-width between min & max - // based on length of data in columns - columnNames.forEach(columnName => { - let column = columns[columnName] - column.width = items - .map(item => item[columnName]) - .reduce((min, cur) => { - // if already at maxWidth don't bother testing - if (min >= column.maxWidth) return min - return Math.max(min, Math.min(column.maxWidth, Math.max(column.minWidth, wcwidth(cur)))) - }, 0) - }) - - // split long words so they can break onto multiple lines - columnNames.forEach(columnName => { - let column = columns[columnName] - items = items.map(item => { - item[columnName] = splitLongWords(item[columnName], column.width, column.truncateMarker) - return item - }) - }) - - // wrap long lines. each item is now an array of lines. - columnNames.forEach(columnName => { - let column = columns[columnName] - items = items.map((item, index) => { - let cell = item[columnName] - item[columnName] = splitIntoLines(cell, column.width) - - // if truncating required, only include first line + add truncation char - if (column.truncate && item[columnName].length > 1) { - item[columnName] = splitIntoLines(cell, column.width - wcwidth(column.truncateMarker)) - let firstLine = item[columnName][0] - if (!endsWith(firstLine, column.truncateMarker)) item[columnName][0] += column.truncateMarker - item[columnName] = item[columnName].slice(0, 1) - } - return item - }) - }) - - // recalculate column widths from truncated output/lines - columnNames.forEach(columnName => { - let column = columns[columnName] - column.width = items.map(item => { - return item[columnName].reduce((min, cur) => { - if (min >= column.maxWidth) return min - return Math.max(min, Math.min(column.maxWidth, Math.max(column.minWidth, wcwidth(cur)))) - }, 0) - }).reduce((min, cur) => { - if (min >= column.maxWidth) return min - return Math.max(min, Math.min(column.maxWidth, Math.max(column.minWidth, cur))) - }, 0) - }) - - - let rows = createRows(items, columns, columnNames, options.paddingChr) // merge lines into rows - // conceive output - return rows.reduce((output, row) => { - return output.concat(row.reduce((rowOut, line) => { - return rowOut.concat(line.join(options.columnSplitter)) - }, [])) - }, []) - .map(line => truncateString(line, maxLineWidth)) - .join(options.spacing) -} - -/** - * Convert wrapped lines into rows with padded values. - * - * @param Array items data to process - * @param Array columns column width settings for wrapping - * @param Array columnNames column ordering - * @return Array items wrapped in arrays, corresponding to lines - */ - -function createRows(items, columns, columnNames, paddingChr) { - return items.map(item => { - let row = [] - let numLines = 0 - columnNames.forEach(columnName => { - numLines = Math.max(numLines, item[columnName].length) - }) - // combine matching lines of each rows - for (let i = 0; i < numLines; i++) { - row[i] = row[i] || [] - columnNames.forEach(columnName => { - let column = columns[columnName] - let val = item[columnName][i] || '' // || '' ensures empty columns get padded - if (column.align === 'right') row[i].push(padLeft(val, column.width, paddingChr)) - else if (column.align === 'center' || column.align === 'centre') row[i].push(padCenter(val, column.width, paddingChr)) - else row[i].push(padRight(val, column.width, paddingChr)) - }) - } - return row - }) -} - -/** - * Object.assign - * - * @return Object Object with properties mixed in. - */ - -function mixin(...args) { - if (Object.assign) return Object.assign(...args) - return ObjectAssign(...args) -} - -function ObjectAssign(target, firstSource) { - "use strict"; - if (target === undefined || target === null) - throw new TypeError("Cannot convert first argument to object"); - - var to = Object(target); - - var hasPendingException = false; - var pendingException; - - for (var i = 1; i < arguments.length; i++) { - var nextSource = arguments[i]; - if (nextSource === undefined || nextSource === null) - continue; - - var keysArray = Object.keys(Object(nextSource)); - for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) { - var nextKey = keysArray[nextIndex]; - try { - var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey); - if (desc !== undefined && desc.enumerable) - to[nextKey] = nextSource[nextKey]; - } catch (e) { - if (!hasPendingException) { - hasPendingException = true; - pendingException = e; - } - } - } - - if (hasPendingException) - throw pendingException; - } - return to; -} - -/** - * Adapted from String.prototype.endsWith polyfill. - */ - -function endsWith(target, searchString, position) { - position = position || target.length; - position = position - searchString.length; - let lastIndex = target.lastIndexOf(searchString); - return lastIndex !== -1 && lastIndex === position; -} - - -function toArray(items, columnNames) { - if (Array.isArray(items)) return items - let rows = [] - for (let key in items) { - let item = {} - item[columnNames[0] || 'key'] = key - item[columnNames[1] || 'value'] = items[key] - rows.push(item) - } - return rows -} diff --git a/deps/npm/node_modules/columnify/package.json b/deps/npm/node_modules/columnify/package.json deleted file mode 100644 index 29565407a8cd7b..00000000000000 --- a/deps/npm/node_modules/columnify/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "columnify", - "version": "1.6.0", - "description": "Render data in text columns. Supports in-column text-wrap.", - "main": "columnify.js", - "scripts": { - "pretest": "npm prune", - "test": "make prepublish && tape test/*.js | tap-spec", - "bench": "npm test && node bench", - "prepublish": "make prepublish" - }, - "babel": { - "presets": [ - "es2015" - ] - }, - "author": "Tim Oxley", - "license": "MIT", - "devDependencies": { - "babel-cli": "^6.26.0", - "babel-preset-es2015": "^6.3.13", - "chalk": "^1.1.1", - "tap-spec": "^5.0.0", - "tape": "^4.4.0" - }, - "repository": { - "type": "git", - "url": "git://github.com/timoxley/columnify.git" - }, - "keywords": [ - "column", - "text", - "ansi", - "console", - "terminal", - "wrap", - "table" - ], - "bugs": { - "url": "https://github.com/timoxley/columnify/issues" - }, - "homepage": "https://github.com/timoxley/columnify", - "engines": { - "node": ">=8.0.0" - }, - "dependencies": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - }, - "directories": { - "test": "test" - } -} diff --git a/deps/npm/node_modules/columnify/utils.js b/deps/npm/node_modules/columnify/utils.js deleted file mode 100644 index df3e6cc44e8561..00000000000000 --- a/deps/npm/node_modules/columnify/utils.js +++ /dev/null @@ -1,193 +0,0 @@ -"use strict" - -var wcwidth = require('./width') - -/** - * repeat string `str` up to total length of `len` - * - * @param String str string to repeat - * @param Number len total length of output string - */ - -function repeatString(str, len) { - return Array.apply(null, {length: len + 1}).join(str).slice(0, len) -} - -/** - * Pad `str` up to total length `max` with `chr`. - * If `str` is longer than `max`, padRight will return `str` unaltered. - * - * @param String str string to pad - * @param Number max total length of output string - * @param String chr optional. Character to pad with. default: ' ' - * @return String padded str - */ - -function padRight(str, max, chr) { - str = str != null ? str : '' - str = String(str) - var length = max - wcwidth(str) - if (length <= 0) return str - return str + repeatString(chr || ' ', length) -} - -/** - * Pad `str` up to total length `max` with `chr`. - * If `str` is longer than `max`, padCenter will return `str` unaltered. - * - * @param String str string to pad - * @param Number max total length of output string - * @param String chr optional. Character to pad with. default: ' ' - * @return String padded str - */ - -function padCenter(str, max, chr) { - str = str != null ? str : '' - str = String(str) - var length = max - wcwidth(str) - if (length <= 0) return str - var lengthLeft = Math.floor(length/2) - var lengthRight = length - lengthLeft - return repeatString(chr || ' ', lengthLeft) + str + repeatString(chr || ' ', lengthRight) -} - -/** - * Pad `str` up to total length `max` with `chr`, on the left. - * If `str` is longer than `max`, padRight will return `str` unaltered. - * - * @param String str string to pad - * @param Number max total length of output string - * @param String chr optional. Character to pad with. default: ' ' - * @return String padded str - */ - -function padLeft(str, max, chr) { - str = str != null ? str : '' - str = String(str) - var length = max - wcwidth(str) - if (length <= 0) return str - return repeatString(chr || ' ', length) + str -} - -/** - * Split a String `str` into lines of maxiumum length `max`. - * Splits on word boundaries. Preserves existing new lines. - * - * @param String str string to split - * @param Number max length of each line - * @return Array Array containing lines. - */ - -function splitIntoLines(str, max) { - function _splitIntoLines(str, max) { - return str.trim().split(' ').reduce(function(lines, word) { - var line = lines[lines.length - 1] - if (line && wcwidth(line.join(' ')) + wcwidth(word) < max) { - lines[lines.length - 1].push(word) // add to line - } - else lines.push([word]) // new line - return lines - }, []).map(function(l) { - return l.join(' ') - }) - } - return str.split('\n').map(function(str) { - return _splitIntoLines(str, max) - }).reduce(function(lines, line) { - return lines.concat(line) - }, []) -} - -/** - * Add spaces and `truncationChar` between words of - * `str` which are longer than `max`. - * - * @param String str string to split - * @param Number max length of each line - * @param Number truncationChar character to append to split words - * @return String - */ - -function splitLongWords(str, max, truncationChar) { - str = str.trim() - var result = [] - var words = str.split(' ') - var remainder = '' - - var truncationWidth = wcwidth(truncationChar) - - while (remainder || words.length) { - if (remainder) { - var word = remainder - remainder = '' - } else { - var word = words.shift() - } - - if (wcwidth(word) > max) { - // slice is based on length no wcwidth - var i = 0 - var wwidth = 0 - var limit = max - truncationWidth - while (i < word.length) { - var w = wcwidth(word.charAt(i)) - if (w + wwidth > limit) { - break - } - wwidth += w - ++i - } - - remainder = word.slice(i) // get remainder - // save remainder for next loop - - word = word.slice(0, i) // grab truncated word - word += truncationChar // add trailing … or whatever - } - result.push(word) - } - - return result.join(' ') -} - - -/** - * Truncate `str` into total width `max` - * If `str` is shorter than `max`, will return `str` unaltered. - * - * @param String str string to truncated - * @param Number max total wcwidth of output string - * @return String truncated str - */ - -function truncateString(str, max) { - - str = str != null ? str : '' - str = String(str) - - if(max == Infinity) return str - - var i = 0 - var wwidth = 0 - while (i < str.length) { - var w = wcwidth(str.charAt(i)) - if(w + wwidth > max) - break - wwidth += w - ++i - } - return str.slice(0, i) -} - - - -/** - * Exports - */ - -module.exports.padRight = padRight -module.exports.padCenter = padCenter -module.exports.padLeft = padLeft -module.exports.splitIntoLines = splitIntoLines -module.exports.splitLongWords = splitLongWords -module.exports.truncateString = truncateString diff --git a/deps/npm/node_modules/columnify/width.js b/deps/npm/node_modules/columnify/width.js deleted file mode 100644 index a9f5333b40b2fa..00000000000000 --- a/deps/npm/node_modules/columnify/width.js +++ /dev/null @@ -1,6 +0,0 @@ -var stripAnsi = require('strip-ansi') -var wcwidth = require('wcwidth') - -module.exports = function(str) { - return wcwidth(stripAnsi(str)) -} diff --git a/deps/npm/node_modules/console-control-strings/LICENSE b/deps/npm/node_modules/console-control-strings/LICENSE deleted file mode 100644 index e756052969b780..00000000000000 --- a/deps/npm/node_modules/console-control-strings/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (c) 2014, Rebecca Turner - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/deps/npm/node_modules/console-control-strings/index.js b/deps/npm/node_modules/console-control-strings/index.js deleted file mode 100644 index bf890348ec6e35..00000000000000 --- a/deps/npm/node_modules/console-control-strings/index.js +++ /dev/null @@ -1,125 +0,0 @@ -'use strict' - -// These tables borrowed from `ansi` - -var prefix = '\x1b[' - -exports.up = function up (num) { - return prefix + (num || '') + 'A' -} - -exports.down = function down (num) { - return prefix + (num || '') + 'B' -} - -exports.forward = function forward (num) { - return prefix + (num || '') + 'C' -} - -exports.back = function back (num) { - return prefix + (num || '') + 'D' -} - -exports.nextLine = function nextLine (num) { - return prefix + (num || '') + 'E' -} - -exports.previousLine = function previousLine (num) { - return prefix + (num || '') + 'F' -} - -exports.horizontalAbsolute = function horizontalAbsolute (num) { - if (num == null) throw new Error('horizontalAboslute requires a column to position to') - return prefix + num + 'G' -} - -exports.eraseData = function eraseData () { - return prefix + 'J' -} - -exports.eraseLine = function eraseLine () { - return prefix + 'K' -} - -exports.goto = function (x, y) { - return prefix + y + ';' + x + 'H' -} - -exports.gotoSOL = function () { - return '\r' -} - -exports.beep = function () { - return '\x07' -} - -exports.hideCursor = function hideCursor () { - return prefix + '?25l' -} - -exports.showCursor = function showCursor () { - return prefix + '?25h' -} - -var colors = { - reset: 0, -// styles - bold: 1, - italic: 3, - underline: 4, - inverse: 7, -// resets - stopBold: 22, - stopItalic: 23, - stopUnderline: 24, - stopInverse: 27, -// colors - white: 37, - black: 30, - blue: 34, - cyan: 36, - green: 32, - magenta: 35, - red: 31, - yellow: 33, - bgWhite: 47, - bgBlack: 40, - bgBlue: 44, - bgCyan: 46, - bgGreen: 42, - bgMagenta: 45, - bgRed: 41, - bgYellow: 43, - - grey: 90, - brightBlack: 90, - brightRed: 91, - brightGreen: 92, - brightYellow: 93, - brightBlue: 94, - brightMagenta: 95, - brightCyan: 96, - brightWhite: 97, - - bgGrey: 100, - bgBrightBlack: 100, - bgBrightRed: 101, - bgBrightGreen: 102, - bgBrightYellow: 103, - bgBrightBlue: 104, - bgBrightMagenta: 105, - bgBrightCyan: 106, - bgBrightWhite: 107 -} - -exports.color = function color (colorWith) { - if (arguments.length !== 1 || !Array.isArray(colorWith)) { - colorWith = Array.prototype.slice.call(arguments) - } - return prefix + colorWith.map(colorNameToCode).join(';') + 'm' -} - -function colorNameToCode (color) { - if (colors[color] != null) return colors[color] - throw new Error('Unknown color or style name: ' + color) -} diff --git a/deps/npm/node_modules/console-control-strings/package.json b/deps/npm/node_modules/console-control-strings/package.json deleted file mode 100644 index eb6c62ae2dac76..00000000000000 --- a/deps/npm/node_modules/console-control-strings/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "console-control-strings", - "version": "1.1.0", - "description": "A library of cross-platform tested terminal/console command strings for doing things like color and cursor positioning. This is a subset of both ansi and vt100. All control codes included work on both Windows & Unix-like OSes, except where noted.", - "main": "index.js", - "directories": { - "test": "test" - }, - "scripts": { - "test": "standard && tap test/*.js" - }, - "repository": { - "type": "git", - "url": "https://github.com/iarna/console-control-strings" - }, - "keywords": [], - "author": "Rebecca Turner (http://re-becca.org/)", - "license": "ISC", - "files": [ - "LICENSE", - "index.js" - ], - "devDependencies": { - "standard": "^7.1.2", - "tap": "^5.7.2" - } -} diff --git a/deps/npm/node_modules/defaults/LICENSE b/deps/npm/node_modules/defaults/LICENSE deleted file mode 100644 index 11eb6fdebf3b63..00000000000000 --- a/deps/npm/node_modules/defaults/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2022 Sindre Sorhus -Copyright (c) 2015 Elijah Insua - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/deps/npm/node_modules/defaults/index.js b/deps/npm/node_modules/defaults/index.js deleted file mode 100644 index cb7d75c9c6beb0..00000000000000 --- a/deps/npm/node_modules/defaults/index.js +++ /dev/null @@ -1,13 +0,0 @@ -var clone = require('clone'); - -module.exports = function(options, defaults) { - options = options || {}; - - Object.keys(defaults).forEach(function(key) { - if (typeof options[key] === 'undefined') { - options[key] = clone(defaults[key]); - } - }); - - return options; -}; \ No newline at end of file diff --git a/deps/npm/node_modules/defaults/package.json b/deps/npm/node_modules/defaults/package.json deleted file mode 100644 index 44f72b1714ce4e..00000000000000 --- a/deps/npm/node_modules/defaults/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "defaults", - "version": "1.0.4", - "description": "merge single level defaults over a config object", - "main": "index.js", - "funding": "https://github.com/sponsors/sindresorhus", - "scripts": { - "test": "node test.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/sindresorhus/node-defaults.git" - }, - "keywords": [ - "config", - "defaults", - "options", - "object", - "merge", - "assign", - "properties", - "deep" - ], - "author": "Elijah Insua ", - "license": "MIT", - "readmeFilename": "README.md", - "dependencies": { - "clone": "^1.0.2" - }, - "devDependencies": { - "tap": "^2.0.0" - } -} diff --git a/deps/npm/node_modules/defaults/test.js b/deps/npm/node_modules/defaults/test.js deleted file mode 100644 index 60e0ffba8b4aab..00000000000000 --- a/deps/npm/node_modules/defaults/test.js +++ /dev/null @@ -1,34 +0,0 @@ -var defaults = require('./'), - test = require('tap').test; - -test("ensure options is an object", function(t) { - var options = defaults(false, { a : true }); - t.ok(options.a); - t.end() -}); - -test("ensure defaults override keys", function(t) { - var result = defaults({}, { a: false, b: true }); - t.ok(result.b, 'b merges over undefined'); - t.equal(result.a, false, 'a merges over undefined'); - t.end(); -}); - -test("ensure defined keys are not overwritten", function(t) { - var result = defaults({ b: false }, { a: false, b: true }); - t.equal(result.b, false, 'b not merged'); - t.equal(result.a, false, 'a merges over undefined'); - t.end(); -}); - -test("ensure defaults clone nested objects", function(t) { - var d = { a: [1,2,3], b: { hello : 'world' } }; - var result = defaults({}, d); - t.equal(result.a.length, 3, 'objects should be clones'); - t.ok(result.a !== d.a, 'objects should be clones'); - - t.equal(Object.keys(result.b).length, 1, 'objects should be clones'); - t.ok(result.b !== d.b, 'objects should be clones'); - t.end(); -}); - diff --git a/deps/npm/node_modules/gauge/LICENSE.md b/deps/npm/node_modules/gauge/LICENSE.md deleted file mode 100644 index 5fc208ff122e08..00000000000000 --- a/deps/npm/node_modules/gauge/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ - - -ISC License - -Copyright npm, Inc. - -Permission to use, copy, modify, and/or distribute this -software for any purpose with or without fee is hereby -granted, provided that the above copyright notice and this -permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO -EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE -USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/deps/npm/node_modules/gauge/lib/base-theme.js b/deps/npm/node_modules/gauge/lib/base-theme.js deleted file mode 100644 index 00bf5684cddab8..00000000000000 --- a/deps/npm/node_modules/gauge/lib/base-theme.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict' -var spin = require('./spin.js') -var progressBar = require('./progress-bar.js') - -module.exports = { - activityIndicator: function (values, theme, width) { - if (values.spun == null) { - return - } - return spin(theme, values.spun) - }, - progressbar: function (values, theme, width) { - if (values.completed == null) { - return - } - return progressBar(theme, width, values.completed) - }, -} diff --git a/deps/npm/node_modules/gauge/lib/error.js b/deps/npm/node_modules/gauge/lib/error.js deleted file mode 100644 index d9914ba5335d25..00000000000000 --- a/deps/npm/node_modules/gauge/lib/error.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict' -var util = require('util') - -var User = exports.User = function User (msg) { - var err = new Error(msg) - Error.captureStackTrace(err, User) - err.code = 'EGAUGE' - return err -} - -exports.MissingTemplateValue = function MissingTemplateValue (item, values) { - var err = new User(util.format('Missing template value "%s"', item.type)) - Error.captureStackTrace(err, MissingTemplateValue) - err.template = item - err.values = values - return err -} - -exports.Internal = function Internal (msg) { - var err = new Error(msg) - Error.captureStackTrace(err, Internal) - err.code = 'EGAUGEINTERNAL' - return err -} diff --git a/deps/npm/node_modules/gauge/lib/has-color.js b/deps/npm/node_modules/gauge/lib/has-color.js deleted file mode 100644 index 16cba0eb47d332..00000000000000 --- a/deps/npm/node_modules/gauge/lib/has-color.js +++ /dev/null @@ -1,4 +0,0 @@ -'use strict' -var colorSupport = require('color-support') - -module.exports = colorSupport().hasBasic diff --git a/deps/npm/node_modules/gauge/lib/index.js b/deps/npm/node_modules/gauge/lib/index.js deleted file mode 100644 index be94f53f3b5f46..00000000000000 --- a/deps/npm/node_modules/gauge/lib/index.js +++ /dev/null @@ -1,289 +0,0 @@ -'use strict' -var Plumbing = require('./plumbing.js') -var hasUnicode = require('has-unicode') -var hasColor = require('./has-color.js') -var onExit = require('signal-exit').onExit -var defaultThemes = require('./themes') -var setInterval = require('./set-interval.js') -var process = require('./process.js') -var setImmediate = require('./set-immediate') - -module.exports = Gauge - -function callWith (obj, method) { - return function () { - return method.call(obj) - } -} - -function Gauge (arg1, arg2) { - var options, writeTo - if (arg1 && arg1.write) { - writeTo = arg1 - options = arg2 || {} - } else if (arg2 && arg2.write) { - writeTo = arg2 - options = arg1 || {} - } else { - writeTo = process.stderr - options = arg1 || arg2 || {} - } - - this._status = { - spun: 0, - section: '', - subsection: '', - } - this._paused = false // are we paused for back pressure? - this._disabled = true // are all progress bar updates disabled? - this._showing = false // do we WANT the progress bar on screen - this._onScreen = false // IS the progress bar on screen - this._needsRedraw = false // should we print something at next tick? - this._hideCursor = options.hideCursor == null ? true : options.hideCursor - this._fixedFramerate = options.fixedFramerate == null - ? !(/^v0\.8\./.test(process.version)) - : options.fixedFramerate - this._lastUpdateAt = null - this._updateInterval = options.updateInterval == null ? 50 : options.updateInterval - - this._themes = options.themes || defaultThemes - this._theme = options.theme - var theme = this._computeTheme(options.theme) - var template = options.template || [ - { type: 'progressbar', length: 20 }, - { type: 'activityIndicator', kerning: 1, length: 1 }, - { type: 'section', kerning: 1, default: '' }, - { type: 'subsection', kerning: 1, default: '' }, - ] - this.setWriteTo(writeTo, options.tty) - var PlumbingClass = options.Plumbing || Plumbing - this._gauge = new PlumbingClass(theme, template, this.getWidth()) - - this._$$doRedraw = callWith(this, this._doRedraw) - this._$$handleSizeChange = callWith(this, this._handleSizeChange) - - this._cleanupOnExit = options.cleanupOnExit == null || options.cleanupOnExit - this._removeOnExit = null - - if (options.enabled || (options.enabled == null && this._tty && this._tty.isTTY)) { - this.enable() - } else { - this.disable() - } -} -Gauge.prototype = {} - -Gauge.prototype.isEnabled = function () { - return !this._disabled -} - -Gauge.prototype.setTemplate = function (template) { - this._gauge.setTemplate(template) - if (this._showing) { - this._requestRedraw() - } -} - -Gauge.prototype._computeTheme = function (theme) { - if (!theme) { - theme = {} - } - if (typeof theme === 'string') { - theme = this._themes.getTheme(theme) - } else if ( - Object.keys(theme).length === 0 || theme.hasUnicode != null || theme.hasColor != null - ) { - var useUnicode = theme.hasUnicode == null ? hasUnicode() : theme.hasUnicode - var useColor = theme.hasColor == null ? hasColor : theme.hasColor - theme = this._themes.getDefault({ - hasUnicode: useUnicode, - hasColor: useColor, - platform: theme.platform, - }) - } - return theme -} - -Gauge.prototype.setThemeset = function (themes) { - this._themes = themes - this.setTheme(this._theme) -} - -Gauge.prototype.setTheme = function (theme) { - this._gauge.setTheme(this._computeTheme(theme)) - if (this._showing) { - this._requestRedraw() - } - this._theme = theme -} - -Gauge.prototype._requestRedraw = function () { - this._needsRedraw = true - if (!this._fixedFramerate) { - this._doRedraw() - } -} - -Gauge.prototype.getWidth = function () { - return ((this._tty && this._tty.columns) || 80) - 1 -} - -Gauge.prototype.setWriteTo = function (writeTo, tty) { - var enabled = !this._disabled - if (enabled) { - this.disable() - } - this._writeTo = writeTo - this._tty = tty || - (writeTo === process.stderr && process.stdout.isTTY && process.stdout) || - (writeTo.isTTY && writeTo) || - this._tty - if (this._gauge) { - this._gauge.setWidth(this.getWidth()) - } - if (enabled) { - this.enable() - } -} - -Gauge.prototype.enable = function () { - if (!this._disabled) { - return - } - this._disabled = false - if (this._tty) { - this._enableEvents() - } - if (this._showing) { - this.show() - } -} - -Gauge.prototype.disable = function () { - if (this._disabled) { - return - } - if (this._showing) { - this._lastUpdateAt = null - this._showing = false - this._doRedraw() - this._showing = true - } - this._disabled = true - if (this._tty) { - this._disableEvents() - } -} - -Gauge.prototype._enableEvents = function () { - if (this._cleanupOnExit) { - this._removeOnExit = onExit(callWith(this, this.disable)) - } - this._tty.on('resize', this._$$handleSizeChange) - if (this._fixedFramerate) { - this.redrawTracker = setInterval(this._$$doRedraw, this._updateInterval) - if (this.redrawTracker.unref) { - this.redrawTracker.unref() - } - } -} - -Gauge.prototype._disableEvents = function () { - this._tty.removeListener('resize', this._$$handleSizeChange) - if (this._fixedFramerate) { - clearInterval(this.redrawTracker) - } - if (this._removeOnExit) { - this._removeOnExit() - } -} - -Gauge.prototype.hide = function (cb) { - if (this._disabled) { - return cb && process.nextTick(cb) - } - if (!this._showing) { - return cb && process.nextTick(cb) - } - this._showing = false - this._doRedraw() - cb && setImmediate(cb) -} - -Gauge.prototype.show = function (section, completed) { - this._showing = true - if (typeof section === 'string') { - this._status.section = section - } else if (typeof section === 'object') { - var sectionKeys = Object.keys(section) - for (var ii = 0; ii < sectionKeys.length; ++ii) { - var key = sectionKeys[ii] - this._status[key] = section[key] - } - } - if (completed != null) { - this._status.completed = completed - } - if (this._disabled) { - return - } - this._requestRedraw() -} - -Gauge.prototype.pulse = function (subsection) { - this._status.subsection = subsection || '' - this._status.spun++ - if (this._disabled) { - return - } - if (!this._showing) { - return - } - this._requestRedraw() -} - -Gauge.prototype._handleSizeChange = function () { - this._gauge.setWidth(this._tty.columns - 1) - this._requestRedraw() -} - -Gauge.prototype._doRedraw = function () { - if (this._disabled || this._paused) { - return - } - if (!this._fixedFramerate) { - var now = Date.now() - if (this._lastUpdateAt && now - this._lastUpdateAt < this._updateInterval) { - return - } - this._lastUpdateAt = now - } - if (!this._showing && this._onScreen) { - this._onScreen = false - var result = this._gauge.hide() - if (this._hideCursor) { - result += this._gauge.showCursor() - } - return this._writeTo.write(result) - } - if (!this._showing && !this._onScreen) { - return - } - if (this._showing && !this._onScreen) { - this._onScreen = true - this._needsRedraw = true - if (this._hideCursor) { - this._writeTo.write(this._gauge.hideCursor()) - } - } - if (!this._needsRedraw) { - return - } - if (!this._writeTo.write(this._gauge.show(this._status))) { - this._paused = true - this._writeTo.on('drain', callWith(this, function () { - this._paused = false - this._doRedraw() - })) - } -} diff --git a/deps/npm/node_modules/gauge/lib/plumbing.js b/deps/npm/node_modules/gauge/lib/plumbing.js deleted file mode 100644 index c4dc3e074b95e8..00000000000000 --- a/deps/npm/node_modules/gauge/lib/plumbing.js +++ /dev/null @@ -1,50 +0,0 @@ -'use strict' -var consoleControl = require('console-control-strings') -var renderTemplate = require('./render-template.js') -var validate = require('aproba') - -var Plumbing = module.exports = function (theme, template, width) { - if (!width) { - width = 80 - } - validate('OAN', [theme, template, width]) - this.showing = false - this.theme = theme - this.width = width - this.template = template -} -Plumbing.prototype = {} - -Plumbing.prototype.setTheme = function (theme) { - validate('O', [theme]) - this.theme = theme -} - -Plumbing.prototype.setTemplate = function (template) { - validate('A', [template]) - this.template = template -} - -Plumbing.prototype.setWidth = function (width) { - validate('N', [width]) - this.width = width -} - -Plumbing.prototype.hide = function () { - return consoleControl.gotoSOL() + consoleControl.eraseLine() -} - -Plumbing.prototype.hideCursor = consoleControl.hideCursor - -Plumbing.prototype.showCursor = consoleControl.showCursor - -Plumbing.prototype.show = function (status) { - var values = Object.create(this.theme) - for (var key in status) { - values[key] = status[key] - } - - return renderTemplate(this.width, this.template, values).trim() + - consoleControl.color('reset') + - consoleControl.eraseLine() + consoleControl.gotoSOL() -} diff --git a/deps/npm/node_modules/gauge/lib/process.js b/deps/npm/node_modules/gauge/lib/process.js deleted file mode 100644 index 05e85694d755b6..00000000000000 --- a/deps/npm/node_modules/gauge/lib/process.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict' -// this exists so we can replace it during testing -module.exports = process diff --git a/deps/npm/node_modules/gauge/lib/progress-bar.js b/deps/npm/node_modules/gauge/lib/progress-bar.js deleted file mode 100644 index 184ff2500aae4d..00000000000000 --- a/deps/npm/node_modules/gauge/lib/progress-bar.js +++ /dev/null @@ -1,41 +0,0 @@ -'use strict' -var validate = require('aproba') -var renderTemplate = require('./render-template.js') -var wideTruncate = require('./wide-truncate') -var stringWidth = require('string-width') - -module.exports = function (theme, width, completed) { - validate('ONN', [theme, width, completed]) - if (completed < 0) { - completed = 0 - } - if (completed > 1) { - completed = 1 - } - if (width <= 0) { - return '' - } - var sofar = Math.round(width * completed) - var rest = width - sofar - var template = [ - { type: 'complete', value: repeat(theme.complete, sofar), length: sofar }, - { type: 'remaining', value: repeat(theme.remaining, rest), length: rest }, - ] - return renderTemplate(width, template, theme) -} - -// lodash's way of repeating -function repeat (string, width) { - var result = '' - var n = width - do { - if (n % 2) { - result += string - } - n = Math.floor(n / 2) - /* eslint no-self-assign: 0 */ - string += string - } while (n && stringWidth(result) < width) - - return wideTruncate(result, width) -} diff --git a/deps/npm/node_modules/gauge/lib/render-template.js b/deps/npm/node_modules/gauge/lib/render-template.js deleted file mode 100644 index d1b52c0f48095a..00000000000000 --- a/deps/npm/node_modules/gauge/lib/render-template.js +++ /dev/null @@ -1,222 +0,0 @@ -'use strict' -var align = require('wide-align') -var validate = require('aproba') -var wideTruncate = require('./wide-truncate') -var error = require('./error') -var TemplateItem = require('./template-item') - -function renderValueWithValues (values) { - return function (item) { - return renderValue(item, values) - } -} - -var renderTemplate = module.exports = function (width, template, values) { - var items = prepareItems(width, template, values) - var rendered = items.map(renderValueWithValues(values)).join('') - return align.left(wideTruncate(rendered, width), width) -} - -function preType (item) { - var cappedTypeName = item.type[0].toUpperCase() + item.type.slice(1) - return 'pre' + cappedTypeName -} - -function postType (item) { - var cappedTypeName = item.type[0].toUpperCase() + item.type.slice(1) - return 'post' + cappedTypeName -} - -function hasPreOrPost (item, values) { - if (!item.type) { - return - } - return values[preType(item)] || values[postType(item)] -} - -function generatePreAndPost (baseItem, parentValues) { - var item = Object.assign({}, baseItem) - var values = Object.create(parentValues) - var template = [] - var pre = preType(item) - var post = postType(item) - if (values[pre]) { - template.push({ value: values[pre] }) - values[pre] = null - } - item.minLength = null - item.length = null - item.maxLength = null - template.push(item) - values[item.type] = values[item.type] - if (values[post]) { - template.push({ value: values[post] }) - values[post] = null - } - return function ($1, $2, length) { - return renderTemplate(length, template, values) - } -} - -function prepareItems (width, template, values) { - function cloneAndObjectify (item, index, arr) { - var cloned = new TemplateItem(item, width) - var type = cloned.type - if (cloned.value == null) { - if (!(type in values)) { - if (cloned.default == null) { - throw new error.MissingTemplateValue(cloned, values) - } else { - cloned.value = cloned.default - } - } else { - cloned.value = values[type] - } - } - if (cloned.value == null || cloned.value === '') { - return null - } - cloned.index = index - cloned.first = index === 0 - cloned.last = index === arr.length - 1 - if (hasPreOrPost(cloned, values)) { - cloned.value = generatePreAndPost(cloned, values) - } - return cloned - } - - var output = template.map(cloneAndObjectify).filter(function (item) { - return item != null - }) - - var remainingSpace = width - var variableCount = output.length - - function consumeSpace (length) { - if (length > remainingSpace) { - length = remainingSpace - } - remainingSpace -= length - } - - function finishSizing (item, length) { - if (item.finished) { - throw new error.Internal('Tried to finish template item that was already finished') - } - if (length === Infinity) { - throw new error.Internal('Length of template item cannot be infinity') - } - if (length != null) { - item.length = length - } - item.minLength = null - item.maxLength = null - --variableCount - item.finished = true - if (item.length == null) { - item.length = item.getBaseLength() - } - if (item.length == null) { - throw new error.Internal('Finished template items must have a length') - } - consumeSpace(item.getLength()) - } - - output.forEach(function (item) { - if (!item.kerning) { - return - } - var prevPadRight = item.first ? 0 : output[item.index - 1].padRight - if (!item.first && prevPadRight < item.kerning) { - item.padLeft = item.kerning - prevPadRight - } - if (!item.last) { - item.padRight = item.kerning - } - }) - - // Finish any that have a fixed (literal or intuited) length - output.forEach(function (item) { - if (item.getBaseLength() == null) { - return - } - finishSizing(item) - }) - - var resized = 0 - var resizing - var hunkSize - do { - resizing = false - hunkSize = Math.round(remainingSpace / variableCount) - output.forEach(function (item) { - if (item.finished) { - return - } - if (!item.maxLength) { - return - } - if (item.getMaxLength() < hunkSize) { - finishSizing(item, item.maxLength) - resizing = true - } - }) - } while (resizing && resized++ < output.length) - if (resizing) { - throw new error.Internal('Resize loop iterated too many times while determining maxLength') - } - - resized = 0 - do { - resizing = false - hunkSize = Math.round(remainingSpace / variableCount) - output.forEach(function (item) { - if (item.finished) { - return - } - if (!item.minLength) { - return - } - if (item.getMinLength() >= hunkSize) { - finishSizing(item, item.minLength) - resizing = true - } - }) - } while (resizing && resized++ < output.length) - if (resizing) { - throw new error.Internal('Resize loop iterated too many times while determining minLength') - } - - hunkSize = Math.round(remainingSpace / variableCount) - output.forEach(function (item) { - if (item.finished) { - return - } - finishSizing(item, hunkSize) - }) - - return output -} - -function renderFunction (item, values, length) { - validate('OON', arguments) - if (item.type) { - return item.value(values, values[item.type + 'Theme'] || {}, length) - } else { - return item.value(values, {}, length) - } -} - -function renderValue (item, values) { - var length = item.getBaseLength() - var value = typeof item.value === 'function' ? renderFunction(item, values, length) : item.value - if (value == null || value === '') { - return '' - } - var alignWith = align[item.align] || align.left - var leftPadding = item.padLeft ? align.left('', item.padLeft) : '' - var rightPadding = item.padRight ? align.right('', item.padRight) : '' - var truncated = wideTruncate(String(value), length) - var aligned = alignWith(truncated, length) - return leftPadding + aligned + rightPadding -} diff --git a/deps/npm/node_modules/gauge/lib/set-immediate.js b/deps/npm/node_modules/gauge/lib/set-immediate.js deleted file mode 100644 index 6650a485c49933..00000000000000 --- a/deps/npm/node_modules/gauge/lib/set-immediate.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict' -var process = require('./process') -try { - module.exports = setImmediate -} catch (ex) { - module.exports = process.nextTick -} diff --git a/deps/npm/node_modules/gauge/lib/set-interval.js b/deps/npm/node_modules/gauge/lib/set-interval.js deleted file mode 100644 index 576198793c5504..00000000000000 --- a/deps/npm/node_modules/gauge/lib/set-interval.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict' -// this exists so we can replace it during testing -module.exports = setInterval diff --git a/deps/npm/node_modules/gauge/lib/spin.js b/deps/npm/node_modules/gauge/lib/spin.js deleted file mode 100644 index 34142ee31acc7c..00000000000000 --- a/deps/npm/node_modules/gauge/lib/spin.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict' - -module.exports = function spin (spinstr, spun) { - return spinstr[spun % spinstr.length] -} diff --git a/deps/npm/node_modules/gauge/lib/template-item.js b/deps/npm/node_modules/gauge/lib/template-item.js deleted file mode 100644 index e307e9b7421e73..00000000000000 --- a/deps/npm/node_modules/gauge/lib/template-item.js +++ /dev/null @@ -1,87 +0,0 @@ -'use strict' -var stringWidth = require('string-width') - -module.exports = TemplateItem - -function isPercent (num) { - if (typeof num !== 'string') { - return false - } - return num.slice(-1) === '%' -} - -function percent (num) { - return Number(num.slice(0, -1)) / 100 -} - -function TemplateItem (values, outputLength) { - this.overallOutputLength = outputLength - this.finished = false - this.type = null - this.value = null - this.length = null - this.maxLength = null - this.minLength = null - this.kerning = null - this.align = 'left' - this.padLeft = 0 - this.padRight = 0 - this.index = null - this.first = null - this.last = null - if (typeof values === 'string') { - this.value = values - } else { - for (var prop in values) { - this[prop] = values[prop] - } - } - // Realize percents - if (isPercent(this.length)) { - this.length = Math.round(this.overallOutputLength * percent(this.length)) - } - if (isPercent(this.minLength)) { - this.minLength = Math.round(this.overallOutputLength * percent(this.minLength)) - } - if (isPercent(this.maxLength)) { - this.maxLength = Math.round(this.overallOutputLength * percent(this.maxLength)) - } - return this -} - -TemplateItem.prototype = {} - -TemplateItem.prototype.getBaseLength = function () { - var length = this.length - if ( - length == null && - typeof this.value === 'string' && - this.maxLength == null && - this.minLength == null - ) { - length = stringWidth(this.value) - } - return length -} - -TemplateItem.prototype.getLength = function () { - var length = this.getBaseLength() - if (length == null) { - return null - } - return length + this.padLeft + this.padRight -} - -TemplateItem.prototype.getMaxLength = function () { - if (this.maxLength == null) { - return null - } - return this.maxLength + this.padLeft + this.padRight -} - -TemplateItem.prototype.getMinLength = function () { - if (this.minLength == null) { - return null - } - return this.minLength + this.padLeft + this.padRight -} diff --git a/deps/npm/node_modules/gauge/lib/theme-set.js b/deps/npm/node_modules/gauge/lib/theme-set.js deleted file mode 100644 index 643d7dbb1da346..00000000000000 --- a/deps/npm/node_modules/gauge/lib/theme-set.js +++ /dev/null @@ -1,122 +0,0 @@ -'use strict' - -module.exports = function () { - return ThemeSetProto.newThemeSet() -} - -var ThemeSetProto = {} - -ThemeSetProto.baseTheme = require('./base-theme.js') - -ThemeSetProto.newTheme = function (parent, theme) { - if (!theme) { - theme = parent - parent = this.baseTheme - } - return Object.assign({}, parent, theme) -} - -ThemeSetProto.getThemeNames = function () { - return Object.keys(this.themes) -} - -ThemeSetProto.addTheme = function (name, parent, theme) { - this.themes[name] = this.newTheme(parent, theme) -} - -ThemeSetProto.addToAllThemes = function (theme) { - var themes = this.themes - Object.keys(themes).forEach(function (name) { - Object.assign(themes[name], theme) - }) - Object.assign(this.baseTheme, theme) -} - -ThemeSetProto.getTheme = function (name) { - if (!this.themes[name]) { - throw this.newMissingThemeError(name) - } - return this.themes[name] -} - -ThemeSetProto.setDefault = function (opts, name) { - if (name == null) { - name = opts - opts = {} - } - var platform = opts.platform == null ? 'fallback' : opts.platform - var hasUnicode = !!opts.hasUnicode - var hasColor = !!opts.hasColor - if (!this.defaults[platform]) { - this.defaults[platform] = { true: {}, false: {} } - } - this.defaults[platform][hasUnicode][hasColor] = name -} - -ThemeSetProto.getDefault = function (opts) { - if (!opts) { - opts = {} - } - var platformName = opts.platform || process.platform - var platform = this.defaults[platformName] || this.defaults.fallback - var hasUnicode = !!opts.hasUnicode - var hasColor = !!opts.hasColor - if (!platform) { - throw this.newMissingDefaultThemeError(platformName, hasUnicode, hasColor) - } - if (!platform[hasUnicode][hasColor]) { - if (hasUnicode && hasColor && platform[!hasUnicode][hasColor]) { - hasUnicode = false - } else if (hasUnicode && hasColor && platform[hasUnicode][!hasColor]) { - hasColor = false - } else if (hasUnicode && hasColor && platform[!hasUnicode][!hasColor]) { - hasUnicode = false - hasColor = false - } else if (hasUnicode && !hasColor && platform[!hasUnicode][hasColor]) { - hasUnicode = false - } else if (!hasUnicode && hasColor && platform[hasUnicode][!hasColor]) { - hasColor = false - } else if (platform === this.defaults.fallback) { - throw this.newMissingDefaultThemeError(platformName, hasUnicode, hasColor) - } - } - if (platform[hasUnicode][hasColor]) { - return this.getTheme(platform[hasUnicode][hasColor]) - } else { - return this.getDefault(Object.assign({}, opts, { platform: 'fallback' })) - } -} - -ThemeSetProto.newMissingThemeError = function newMissingThemeError (name) { - var err = new Error('Could not find a gauge theme named "' + name + '"') - Error.captureStackTrace.call(err, newMissingThemeError) - err.theme = name - err.code = 'EMISSINGTHEME' - return err -} - -ThemeSetProto.newMissingDefaultThemeError = - function newMissingDefaultThemeError (platformName, hasUnicode, hasColor) { - var err = new Error( - 'Could not find a gauge theme for your platform/unicode/color use combo:\n' + - ' platform = ' + platformName + '\n' + - ' hasUnicode = ' + hasUnicode + '\n' + - ' hasColor = ' + hasColor) - Error.captureStackTrace.call(err, newMissingDefaultThemeError) - err.platform = platformName - err.hasUnicode = hasUnicode - err.hasColor = hasColor - err.code = 'EMISSINGTHEME' - return err - } - -ThemeSetProto.newThemeSet = function () { - var themeset = function (opts) { - return themeset.getDefault(opts) - } - return Object.assign(themeset, ThemeSetProto, { - themes: Object.assign({}, this.themes), - baseTheme: Object.assign({}, this.baseTheme), - defaults: JSON.parse(JSON.stringify(this.defaults || {})), - }) -} diff --git a/deps/npm/node_modules/gauge/lib/themes.js b/deps/npm/node_modules/gauge/lib/themes.js deleted file mode 100644 index d2e62bbccb3d82..00000000000000 --- a/deps/npm/node_modules/gauge/lib/themes.js +++ /dev/null @@ -1,56 +0,0 @@ -'use strict' -var color = require('console-control-strings').color -var ThemeSet = require('./theme-set.js') - -var themes = module.exports = new ThemeSet() - -themes.addTheme('ASCII', { - preProgressbar: '[', - postProgressbar: ']', - progressbarTheme: { - complete: '#', - remaining: '.', - }, - activityIndicatorTheme: '-\\|/', - preSubsection: '>', -}) - -themes.addTheme('colorASCII', themes.getTheme('ASCII'), { - progressbarTheme: { - preComplete: color('bgBrightWhite', 'brightWhite'), - complete: '#', - postComplete: color('reset'), - preRemaining: color('bgBrightBlack', 'brightBlack'), - remaining: '.', - postRemaining: color('reset'), - }, -}) - -themes.addTheme('brailleSpinner', { - preProgressbar: '(', - postProgressbar: ')', - progressbarTheme: { - complete: '#', - remaining: '⠂', - }, - activityIndicatorTheme: '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏', - preSubsection: '>', -}) - -themes.addTheme('colorBrailleSpinner', themes.getTheme('brailleSpinner'), { - progressbarTheme: { - preComplete: color('bgBrightWhite', 'brightWhite'), - complete: '#', - postComplete: color('reset'), - preRemaining: color('bgBrightBlack', 'brightBlack'), - remaining: '⠂', - postRemaining: color('reset'), - }, -}) - -themes.setDefault({}, 'ASCII') -themes.setDefault({ hasColor: true }, 'colorASCII') -themes.setDefault({ platform: 'darwin', hasUnicode: true }, 'brailleSpinner') -themes.setDefault({ platform: 'darwin', hasUnicode: true, hasColor: true }, 'colorBrailleSpinner') -themes.setDefault({ platform: 'linux', hasUnicode: true }, 'brailleSpinner') -themes.setDefault({ platform: 'linux', hasUnicode: true, hasColor: true }, 'colorBrailleSpinner') diff --git a/deps/npm/node_modules/gauge/lib/wide-truncate.js b/deps/npm/node_modules/gauge/lib/wide-truncate.js deleted file mode 100644 index 5284a699ac3fb5..00000000000000 --- a/deps/npm/node_modules/gauge/lib/wide-truncate.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict' -var stringWidth = require('string-width') -var stripAnsi = require('strip-ansi') - -module.exports = wideTruncate - -function wideTruncate (str, target) { - if (stringWidth(str) === 0) { - return str - } - if (target <= 0) { - return '' - } - if (stringWidth(str) <= target) { - return str - } - - // We compute the number of bytes of ansi sequences here and add - // that to our initial truncation to ensure that we don't slice one - // that we want to keep in half. - var noAnsi = stripAnsi(str) - var ansiSize = str.length + noAnsi.length - var truncated = str.slice(0, target + ansiSize) - - // we have to shrink the result to account for our ansi sequence buffer - // (if an ansi sequence was truncated) and double width characters. - while (stringWidth(truncated) > target) { - truncated = truncated.slice(0, -1) - } - return truncated -} diff --git a/deps/npm/node_modules/gauge/package.json b/deps/npm/node_modules/gauge/package.json deleted file mode 100644 index 449d9dd3ed3920..00000000000000 --- a/deps/npm/node_modules/gauge/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "gauge", - "version": "5.0.1", - "description": "A terminal based horizontal gauge", - "main": "lib", - "scripts": { - "test": "tap", - "lint": "eslint \"**/*.js\"", - "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", - "snap": "tap", - "posttest": "npm run lint", - "template-oss-apply": "template-oss-apply --force" - }, - "repository": { - "type": "git", - "url": "https://github.com/npm/gauge.git" - }, - "keywords": [ - "progressbar", - "progress", - "gauge" - ], - "author": "GitHub Inc.", - "license": "ISC", - "bugs": { - "url": "https://github.com/npm/gauge/issues" - }, - "homepage": "https://github.com/npm/gauge", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^4.0.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "devDependencies": { - "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.14.1", - "readable-stream": "^4.0.0", - "tap": "^16.0.1" - }, - "files": [ - "bin/", - "lib/" - ], - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "tap": { - "branches": 79, - "statements": 89, - "functions": 92, - "lines": 90, - "nyc-arg": [ - "--exclude", - "tap-snapshots/**" - ] - }, - "templateOSS": { - "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.14.1", - "publish": "true" - } -} diff --git a/deps/npm/node_modules/has-unicode/LICENSE b/deps/npm/node_modules/has-unicode/LICENSE deleted file mode 100644 index d42e25e95655bb..00000000000000 --- a/deps/npm/node_modules/has-unicode/LICENSE +++ /dev/null @@ -1,14 +0,0 @@ -Copyright (c) 2014, Rebecca Turner - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/deps/npm/node_modules/has-unicode/index.js b/deps/npm/node_modules/has-unicode/index.js deleted file mode 100644 index 9b0fe445401311..00000000000000 --- a/deps/npm/node_modules/has-unicode/index.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict" -var os = require("os") - -var hasUnicode = module.exports = function () { - // Recent Win32 platforms (>XP) CAN support unicode in the console but - // don't have to, and in non-english locales often use traditional local - // code pages. There's no way, short of windows system calls or execing - // the chcp command line program to figure this out. As such, we default - // this to false and encourage your users to override it via config if - // appropriate. - if (os.type() == "Windows_NT") { return false } - - var isUTF8 = /UTF-?8$/i - var ctype = process.env.LC_ALL || process.env.LC_CTYPE || process.env.LANG - return isUTF8.test(ctype) -} diff --git a/deps/npm/node_modules/has-unicode/package.json b/deps/npm/node_modules/has-unicode/package.json deleted file mode 100644 index ebe9d76d621587..00000000000000 --- a/deps/npm/node_modules/has-unicode/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "has-unicode", - "version": "2.0.1", - "description": "Try to guess if your terminal supports unicode", - "main": "index.js", - "scripts": { - "test": "tap test/*.js" - }, - "repository": { - "type": "git", - "url": "https://github.com/iarna/has-unicode" - }, - "keywords": [ - "unicode", - "terminal" - ], - "files": [ - "index.js" - ], - "author": "Rebecca Turner ", - "license": "ISC", - "bugs": { - "url": "https://github.com/iarna/has-unicode/issues" - }, - "homepage": "https://github.com/iarna/has-unicode", - "devDependencies": { - "require-inject": "^1.3.0", - "tap": "^2.3.1" - } -} diff --git a/deps/npm/node_modules/libnpmaccess/package.json b/deps/npm/node_modules/libnpmaccess/package.json index 81a87d6395455e..59b5afa7c7b5f6 100644 --- a/deps/npm/node_modules/libnpmaccess/package.json +++ b/deps/npm/node_modules/libnpmaccess/package.json @@ -1,6 +1,6 @@ { "name": "libnpmaccess", - "version": "8.0.3", + "version": "8.0.5", "description": "programmatic library for `npm access` commands", "author": "GitHub Inc.", "license": "ISC", @@ -23,14 +23,14 @@ }, "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/libnpmaccess" }, "bugs": "https://github.com/npm/libnpmaccess/issues", "homepage": "https://npmjs.com/package/libnpmaccess", "dependencies": { - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.2.0" + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" diff --git a/deps/npm/node_modules/libnpmdiff/lib/format-diff.js b/deps/npm/node_modules/libnpmdiff/lib/format-diff.js index 211386cb5390ee..a6606d94b8b302 100644 --- a/deps/npm/node_modules/libnpmdiff/lib/format-diff.js +++ b/deps/npm/node_modules/libnpmdiff/lib/format-diff.js @@ -1,10 +1,24 @@ -const EOL = '\n' - -const colorizeDiff = require('@npmcli/disparity-colors') const jsDiff = require('diff') const shouldPrintPatch = require('./should-print-patch.js') +const colors = { + // red + removed: { open: '\x1B[31m', close: '\x1B[39m' }, + // green + added: { open: '\x1B[32m', close: '\x1B[39m' }, + // blue + header: { open: '\x1B[34m', close: '\x1B[39m' }, + // cyan + section: { open: '\x1B[36m', close: '\x1B[39m' }, +} + +const color = (colorStr, colorId) => { + const { open, close } = colors[colorId] + // avoid highlighting the "\n" (would highlight till the end of the line) + return colorStr.replace(/[^\n\r]+/g, open + '$&' + close) +} + const formatDiff = ({ files, opts = {}, refs, versions }) => { let res = '' const srcPrefix = opts.diffNoPrefix ? '' : opts.diffSrcPrefix || 'a/' @@ -35,7 +49,7 @@ const formatDiff = ({ files, opts = {}, refs, versions }) => { } if (opts.diffNameOnly) { - res += `${filename}${EOL}` + res += `${filename}\n` continue } @@ -43,7 +57,7 @@ const formatDiff = ({ files, opts = {}, refs, versions }) => { let headerLength = 0 const header = str => { headerLength++ - patch += `${str}${EOL}` + patch += `${str}\n` } // manually build a git diff-compatible header @@ -85,9 +99,17 @@ const formatDiff = ({ files, opts = {}, refs, versions }) => { header(`+++ ${names.b}`) } - res += (opts.color - ? colorizeDiff(patch, { headerLength }) - : patch) + if (opts.color) { + // this RegExp will include all the `\n` chars into the lines, easier to join + const lines = patch.split(/^/m) + res += color(lines.slice(0, headerLength).join(''), 'header') + res += lines.slice(headerLength).join('') + .replace(/^-.*/gm, color('$&', 'removed')) + .replace(/^\+.*/gm, color('$&', 'added')) + .replace(/^@@.+@@/gm, color('$&', 'section')) + } else { + res += patch + } } return res.trim() diff --git a/deps/npm/node_modules/libnpmdiff/lib/tarball.js b/deps/npm/node_modules/libnpmdiff/lib/tarball.js index 930d624f2d5b6a..41ea84a6885a5e 100644 --- a/deps/npm/node_modules/libnpmdiff/lib/tarball.js +++ b/deps/npm/node_modules/libnpmdiff/lib/tarball.js @@ -9,7 +9,7 @@ const tar = require('tar') // returns a simplified tarball when reading files from node_modules folder, // thus avoiding running the prepare scripts and the extra logic from packlist -const nodeModulesTarball = (manifest, opts) => +const nodeModulesTarball = (manifest) => pkgContents({ path: manifest._resolved, depth: 1 }) .then(files => files.map(file => relative(manifest._resolved, file)) diff --git a/deps/npm/node_modules/libnpmdiff/package.json b/deps/npm/node_modules/libnpmdiff/package.json index 98229e99bd5618..d601ff61ca0218 100644 --- a/deps/npm/node_modules/libnpmdiff/package.json +++ b/deps/npm/node_modules/libnpmdiff/package.json @@ -1,10 +1,10 @@ { "name": "libnpmdiff", - "version": "6.0.9", + "version": "6.1.1", "description": "The registry diff", "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/libnpmdiff" }, "main": "lib/index.js", @@ -47,13 +47,12 @@ }, "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/disparity-colors": "^3.0.0", - "@npmcli/installed-package-contents": "^2.0.2", + "@npmcli/installed-package-contents": "^2.1.0", "binary-extensions": "^2.3.0", "diff": "^5.1.0", "minimatch": "^9.0.4", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.1", "tar": "^6.2.1" }, "templateOSS": { diff --git a/deps/npm/node_modules/libnpmexec/README.md b/deps/npm/node_modules/libnpmexec/README.md index fb4a1e32b18df7..acd037c110b4ba 100644 --- a/deps/npm/node_modules/libnpmexec/README.md +++ b/deps/npm/node_modules/libnpmexec/README.md @@ -35,7 +35,6 @@ await libexec({ - `localBin`: Location to the `node_modules/.bin` folder of the local project to start scanning for bin files **String**, defaults to `./node_modules/.bin`. **libexec** will walk up the directory structure looking for `node_modules/.bin` folders in parent folders that might satisfy the current `arg` and will use that bin if found. - `locationMsg`: Overrides "at location" message when entering interactive mode **String** - `globalBin`: Location to the global space bin folder, same as: `$(npm bin -g)` **String**, defaults to empty string. - - `output`: A function to print output to **Function** - `packages`: A list of packages to be used (possibly fetch from the registry) **Array**, defaults to `[]` - `path`: Location to where to read local project info (`package.json`) **String**, defaults to `.` - `runPath`: Location to where to execute the script **String**, defaults to `.` diff --git a/deps/npm/node_modules/libnpmexec/lib/index.js b/deps/npm/node_modules/libnpmexec/lib/index.js index 6f548b943e2e65..28cba79a7f227a 100644 --- a/deps/npm/node_modules/libnpmexec/lib/index.js +++ b/deps/npm/node_modules/libnpmexec/lib/index.js @@ -4,19 +4,16 @@ const { mkdir } = require('fs/promises') const Arborist = require('@npmcli/arborist') const ciInfo = require('ci-info') const crypto = require('crypto') -const log = require('proc-log') +const { log, input } = require('proc-log') const npa = require('npm-package-arg') -const npmlog = require('npmlog') const pacote = require('pacote') const { read } = require('read') const semver = require('semver') - const { fileExists, localFileExists } = require('./file-exists.js') const getBinFromManifest = require('./get-bin-from-manifest.js') const noTTY = require('./no-tty.js') const runScript = require('./run-script.js') const isWindows = require('./is-windows.js') - const { dirname, resolve } = require('path') const binPaths = [] @@ -84,7 +81,6 @@ const exec = async (opts) => { locationMsg = undefined, globalBin = '', globalPath, - output, // dereference values because we manipulate it later packages: [...packages] = [], path = '.', @@ -99,7 +95,6 @@ const exec = async (opts) => { call, flatOptions, locationMsg, - output, path, binPaths, runPath, @@ -245,27 +240,24 @@ const exec = async (opts) => { if (add.length) { if (!yes) { - const missingPackages = add.map(a => `${a.replace(/@$/, '')}`) + const addList = add.map(a => `${a.replace(/@$/, '')}`) + // set -n to always say no if (yes === false) { // Error message lists missing package(s) when process is canceled /* eslint-disable-next-line max-len */ - throw new Error(`npx canceled due to missing packages and no YES option: ${JSON.stringify(missingPackages)}`) + throw new Error(`npx canceled due to missing packages and no YES option: ${JSON.stringify(addList)}`) } if (noTTY() || ciInfo.isCI) { - log.warn('exec', `The following package${ - add.length === 1 ? ' was' : 's were' - } not found and will be installed: ${ - add.map((pkg) => pkg.replace(/@$/, '')).join(', ') - }`) + /* eslint-disable-next-line max-len */ + log.warn('exec', `The following package${add.length === 1 ? ' was' : 's were'} not found and will be installed: ${addList.join(', ')}`) } else { - const addList = missingPackages.join('\n') + '\n' - const prompt = `Need to install the following packages:\n${ - addList - }Ok to proceed? ` - npmlog.clearProgress() - const confirm = await read({ prompt, default: 'y' }) + const confirm = await input.read(() => read({ + /* eslint-disable-next-line max-len */ + prompt: `Need to install the following packages:\n${addList.join('\n')}\nOk to proceed? `, + default: 'y', + })) if (confirm.trim().toLowerCase().charAt(0) !== 'y') { throw new Error('canceled') } diff --git a/deps/npm/node_modules/libnpmexec/lib/run-script.js b/deps/npm/node_modules/libnpmexec/lib/run-script.js index 89dcf2e653036e..1f621edcbc9aa2 100644 --- a/deps/npm/node_modules/libnpmexec/lib/run-script.js +++ b/deps/npm/node_modules/libnpmexec/lib/run-script.js @@ -1,8 +1,7 @@ const ciInfo = require('ci-info') const runScript = require('@npmcli/run-script') const readPackageJson = require('read-package-json-fast') -const npmlog = require('npmlog') -const log = require('proc-log') +const { log, output } = require('proc-log') const noTTY = require('./no-tty.js') const run = async ({ @@ -10,7 +9,6 @@ const run = async ({ call, flatOptions, locationMsg, - output = () => {}, path, binPaths, runPath, @@ -21,8 +19,7 @@ const run = async ({ // do the fakey runScript dance // still should work if no package.json in cwd - const realPkg = await readPackageJson(`${path}/package.json`) - .catch(() => ({})) + const realPkg = await readPackageJson(`${path}/package.json`).catch(() => ({})) const pkg = { ...realPkg, scripts: { @@ -31,41 +28,34 @@ const run = async ({ }, } - npmlog.disableProgress() - - try { - if (script === scriptShell) { - if (!noTTY()) { - if (ciInfo.isCI) { - return log.warn('exec', 'Interactive mode disabled in CI environment') - } + if (script === scriptShell) { + if (!noTTY()) { + if (ciInfo.isCI) { + return log.warn('exec', 'Interactive mode disabled in CI environment') + } - locationMsg = locationMsg || ` at location:\n${flatOptions.chalk.dim(runPath)}` + const { chalk } = flatOptions - output(`${ - flatOptions.chalk.reset('\nEntering npm script environment') - }${ - flatOptions.chalk.reset(locationMsg) - }${ - flatOptions.chalk.bold('\nType \'exit\' or ^D when finished\n') - }`) - } + output.standard(`${ + chalk.reset('\nEntering npm script environment') + }${ + chalk.reset(locationMsg || ` at location:\n${chalk.dim(runPath)}`) + }${ + chalk.bold('\nType \'exit\' or ^D when finished\n') + }`) } - return await runScript({ - ...flatOptions, - pkg, - banner: false, - // we always run in cwd, not --prefix - path: runPath, - binPaths, - event: 'npx', - args, - stdio: 'inherit', - scriptShell, - }) - } finally { - npmlog.enableProgress() } + return runScript({ + ...flatOptions, + pkg, + // we always run in cwd, not --prefix + path: runPath, + binPaths, + event: 'npx', + args, + stdio: 'inherit', + scriptShell, + }) } module.exports = run diff --git a/deps/npm/node_modules/libnpmexec/package.json b/deps/npm/node_modules/libnpmexec/package.json index 39f12270e35a7e..fcb30087cb5d22 100644 --- a/deps/npm/node_modules/libnpmexec/package.json +++ b/deps/npm/node_modules/libnpmexec/package.json @@ -1,6 +1,6 @@ { "name": "libnpmexec", - "version": "7.0.10", + "version": "8.1.0", "files": [ "bin/", "lib/" @@ -12,7 +12,7 @@ "description": "npm exec (npx) programmatic API", "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/libnpmexec" }, "keywords": [ @@ -60,12 +60,11 @@ }, "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", + "@npmcli/run-script": "^8.1.0", "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.1", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", - "proc-log": "^3.0.0", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.1", + "proc-log": "^4.2.0", "read": "^3.0.1", "read-package-json-fast": "^3.0.2", "semver": "^7.3.7", diff --git a/deps/npm/node_modules/libnpmfund/lib/index.js b/deps/npm/node_modules/libnpmfund/lib/index.js index a53893dc1cf87b..39b69afc0abcc5 100644 --- a/deps/npm/node_modules/libnpmfund/lib/index.js +++ b/deps/npm/node_modules/libnpmfund/lib/index.js @@ -133,7 +133,7 @@ function readTree (tree, opts) { }) return directDepsWithFunding.reduce( - (res, { node, fundingItem }, i) => { + (res, { node, fundingItem }) => { if (!fundingItem || fundingItem.length === 0 || !node) { diff --git a/deps/npm/node_modules/libnpmfund/package.json b/deps/npm/node_modules/libnpmfund/package.json index 978252999e92eb..70a53646910a57 100644 --- a/deps/npm/node_modules/libnpmfund/package.json +++ b/deps/npm/node_modules/libnpmfund/package.json @@ -1,6 +1,6 @@ { "name": "libnpmfund", - "version": "5.0.7", + "version": "5.0.9", "main": "lib/index.js", "files": [ "bin/", @@ -9,7 +9,7 @@ "description": "Programmatic API for npm fund", "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/libnpmfund" }, "keywords": [ diff --git a/deps/npm/node_modules/libnpmhook/package.json b/deps/npm/node_modules/libnpmhook/package.json index 7613c1c86fbc1c..2cfa16df091be3 100644 --- a/deps/npm/node_modules/libnpmhook/package.json +++ b/deps/npm/node_modules/libnpmhook/package.json @@ -1,6 +1,6 @@ { "name": "libnpmhook", - "version": "10.0.2", + "version": "10.0.4", "description": "programmatic API for managing npm registry hooks", "main": "lib/index.js", "files": [ @@ -18,7 +18,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/libnpmhook" }, "keywords": [ @@ -31,7 +31,7 @@ "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^17.0.0" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", diff --git a/deps/npm/node_modules/libnpmorg/package.json b/deps/npm/node_modules/libnpmorg/package.json index 49671afd46371a..1a7486bfc681d2 100644 --- a/deps/npm/node_modules/libnpmorg/package.json +++ b/deps/npm/node_modules/libnpmorg/package.json @@ -1,6 +1,6 @@ { "name": "libnpmorg", - "version": "6.0.3", + "version": "6.0.5", "description": "Programmatic api for `npm org` commands", "author": "GitHub Inc.", "main": "lib/index.js", @@ -35,14 +35,14 @@ }, "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/libnpmorg" }, "bugs": "https://github.com/npm/libnpmorg/issues", "homepage": "https://npmjs.com/package/libnpmorg", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" diff --git a/deps/npm/node_modules/libnpmpack/lib/index.js b/deps/npm/node_modules/libnpmpack/lib/index.js index 70d67d360f0d9b..c71716cf544285 100644 --- a/deps/npm/node_modules/libnpmpack/lib/index.js +++ b/deps/npm/node_modules/libnpmpack/lib/index.js @@ -4,9 +4,8 @@ const pacote = require('pacote') const npa = require('npm-package-arg') const runScript = require('@npmcli/run-script') const path = require('path') -const util = require('util') const Arborist = require('@npmcli/arborist') -const writeFile = util.promisify(require('fs').writeFile) +const { writeFile } = require('fs/promises') module.exports = pack async function pack (spec = 'file:.', opts = {}) { @@ -15,10 +14,6 @@ async function pack (spec = 'file:.', opts = {}) { const manifest = await pacote.manifest(spec, opts) - // Default to true if no log options passed, set to false if we're in silent - // mode - const banner = !opts.silent - const stdio = opts.foregroundScripts ? 'inherit' : 'pipe' if (spec.type === 'directory' && !opts.ignoreScripts) { @@ -29,7 +24,6 @@ async function pack (spec = 'file:.', opts = {}) { path: spec.fetchSpec, stdio, pkg: manifest, - banner, }) } @@ -56,7 +50,6 @@ async function pack (spec = 'file:.', opts = {}) { path: spec.fetchSpec, stdio, pkg: manifest, - banner, env: { npm_package_from: tarball.from, npm_package_resolved: tarball.resolved, diff --git a/deps/npm/node_modules/libnpmpack/package.json b/deps/npm/node_modules/libnpmpack/package.json index 1782ab7143186a..9e40f294cc54f6 100644 --- a/deps/npm/node_modules/libnpmpack/package.json +++ b/deps/npm/node_modules/libnpmpack/package.json @@ -1,6 +1,6 @@ { "name": "libnpmpack", - "version": "6.0.9", + "version": "7.0.1", "description": "Programmatic API for the bits behind npm pack", "author": "GitHub Inc.", "main": "lib/index.js", @@ -30,16 +30,16 @@ }, "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/libnpmpack" }, "bugs": "https://github.com/npm/libnpmpack/issues", "homepage": "https://npmjs.com/package/libnpmpack", "dependencies": { "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4" + "@npmcli/run-script": "^8.1.0", + "npm-package-arg": "^11.0.2", + "pacote": "^18.0.1" }, "engines": { "node": "^16.14.0 || >=18.0.0" diff --git a/deps/npm/node_modules/libnpmpublish/lib/publish.js b/deps/npm/node_modules/libnpmpublish/lib/publish.js index b0ef782a166c66..9ffbc934263099 100644 --- a/deps/npm/node_modules/libnpmpublish/lib/publish.js +++ b/deps/npm/node_modules/libnpmpublish/lib/publish.js @@ -1,7 +1,7 @@ const { fixer } = require('normalize-package-data') const npmFetch = require('npm-registry-fetch') const npa = require('npm-package-arg') -const log = require('proc-log') +const { log } = require('proc-log') const semver = require('semver') const { URL } = require('url') const ssri = require('ssri') diff --git a/deps/npm/node_modules/libnpmpublish/package.json b/deps/npm/node_modules/libnpmpublish/package.json index 34f642794af40f..31faaa7b59f266 100644 --- a/deps/npm/node_modules/libnpmpublish/package.json +++ b/deps/npm/node_modules/libnpmpublish/package.json @@ -1,6 +1,6 @@ { "name": "libnpmpublish", - "version": "9.0.5", + "version": "9.0.7", "description": "Programmatic API for the bits behind npm publish and unpublish", "author": "GitHub Inc.", "main": "lib/index.js", @@ -32,7 +32,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/libnpmpublish" }, "bugs": "https://github.com/npm/cli/issues", @@ -40,9 +40,9 @@ "dependencies": { "ci-info": "^4.0.0", "normalize-package-data": "^6.0.0", - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.2.0", - "proc-log": "^3.0.0", + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.2.0", "semver": "^7.3.7", "sigstore": "^2.2.0", "ssri": "^10.0.5" diff --git a/deps/npm/node_modules/libnpmsearch/package.json b/deps/npm/node_modules/libnpmsearch/package.json index c27673d2202c06..cb21747310eaec 100644 --- a/deps/npm/node_modules/libnpmsearch/package.json +++ b/deps/npm/node_modules/libnpmsearch/package.json @@ -1,6 +1,6 @@ { "name": "libnpmsearch", - "version": "7.0.2", + "version": "7.0.4", "description": "Programmatic API for searching in npm and compatible registries.", "author": "GitHub Inc.", "main": "lib/index.js", @@ -32,13 +32,13 @@ }, "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/libnpmsearch" }, "bugs": "https://github.com/npm/libnpmsearch/issues", "homepage": "https://npmjs.com/package/libnpmsearch", "dependencies": { - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" diff --git a/deps/npm/node_modules/libnpmteam/package.json b/deps/npm/node_modules/libnpmteam/package.json index 110304fa0a156d..94f264bd93bf7c 100644 --- a/deps/npm/node_modules/libnpmteam/package.json +++ b/deps/npm/node_modules/libnpmteam/package.json @@ -1,7 +1,7 @@ { "name": "libnpmteam", "description": "npm Team management APIs", - "version": "6.0.2", + "version": "6.0.4", "author": "GitHub Inc.", "license": "ISC", "main": "lib/index.js", @@ -22,7 +22,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/libnpmteam" }, "files": [ @@ -32,7 +32,7 @@ "homepage": "https://npmjs.com/package/libnpmteam", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^16.2.0" + "npm-registry-fetch": "^17.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" diff --git a/deps/npm/node_modules/libnpmversion/README.md b/deps/npm/node_modules/libnpmversion/README.md index ac9ee50ae35d91..857c4d52dc1831 100644 --- a/deps/npm/node_modules/libnpmversion/README.md +++ b/deps/npm/node_modules/libnpmversion/README.md @@ -31,7 +31,6 @@ npmVersion(arg, { ignoreScripts: false, // do not run pre/post/version lifecycle scripts scriptShell: '/bin/bash', // shell to run lifecycle scripts in message: 'v%s', // message for tag and commit, replace %s with the version - silent: false, // passed to @npmcli/run-script to control whether it logs }).then(newVersion => { console.error('version updated!', newVersion) }) diff --git a/deps/npm/node_modules/libnpmversion/lib/enforce-clean.js b/deps/npm/node_modules/libnpmversion/lib/enforce-clean.js index 721f146221c155..25ebb5590e9171 100644 --- a/deps/npm/node_modules/libnpmversion/lib/enforce-clean.js +++ b/deps/npm/node_modules/libnpmversion/lib/enforce-clean.js @@ -1,5 +1,5 @@ const git = require('@npmcli/git') -const log = require('proc-log') +const { log } = require('proc-log') // returns true if it's cool to do git stuff // throws if it's unclean, and not forced. diff --git a/deps/npm/node_modules/libnpmversion/lib/index.js b/deps/npm/node_modules/libnpmversion/lib/index.js index 95acd11b5e4331..4d2fb45945a7b9 100644 --- a/deps/npm/node_modules/libnpmversion/lib/index.js +++ b/deps/npm/node_modules/libnpmversion/lib/index.js @@ -15,7 +15,6 @@ module.exports = async (newversion, opts = {}) => { scriptShell = undefined, preid = null, message = 'v%s', - silent, } = opts const pkg = opts.pkg || await readJson(path + '/package.json') @@ -35,6 +34,5 @@ module.exports = async (newversion, opts = {}) => { preid, pkg, message, - silent, }) } diff --git a/deps/npm/node_modules/libnpmversion/lib/read-json.js b/deps/npm/node_modules/libnpmversion/lib/read-json.js index 2dd0f7aa4902e8..32c7289507697f 100644 --- a/deps/npm/node_modules/libnpmversion/lib/read-json.js +++ b/deps/npm/node_modules/libnpmversion/lib/read-json.js @@ -1,7 +1,6 @@ // can't use read-package-json-fast, because we want to ensure // that we make as few changes as possible, even for safety issues. -const { promisify } = require('util') -const readFile = promisify(require('fs').readFile) +const { readFile } = require('fs/promises') const parse = require('json-parse-even-better-errors') module.exports = async path => parse(await readFile(path)) diff --git a/deps/npm/node_modules/libnpmversion/lib/version.js b/deps/npm/node_modules/libnpmversion/lib/version.js index f14b95e3233f06..bfcd8a521496d5 100644 --- a/deps/npm/node_modules/libnpmversion/lib/version.js +++ b/deps/npm/node_modules/libnpmversion/lib/version.js @@ -8,7 +8,7 @@ const readJson = require('./read-json.js') const git = require('@npmcli/git') const commit = require('./commit.js') const tag = require('./tag.js') -const log = require('proc-log') +const { log } = require('proc-log') const runScript = require('@npmcli/run-script') @@ -20,7 +20,6 @@ module.exports = async (newversion, opts) => { ignoreScripts, preid, pkg, - silent, } = opts const { valid, clean, inc } = semver @@ -65,7 +64,6 @@ module.exports = async (newversion, opts) => { pkg, stdio: 'inherit', event: 'preversion', - banner: !silent, env: { npm_old_version: current, npm_new_version: newV, @@ -101,7 +99,6 @@ module.exports = async (newversion, opts) => { pkg, stdio: 'inherit', event: 'version', - banner: !silent, env: { npm_old_version: current, npm_new_version: newV, @@ -128,7 +125,6 @@ module.exports = async (newversion, opts) => { pkg, stdio: 'inherit', event: 'postversion', - banner: !silent, env: { npm_old_version: current, npm_new_version: newV, diff --git a/deps/npm/node_modules/libnpmversion/lib/write-json.js b/deps/npm/node_modules/libnpmversion/lib/write-json.js index f066d72c67e124..425be8e8e3efb2 100644 --- a/deps/npm/node_modules/libnpmversion/lib/write-json.js +++ b/deps/npm/node_modules/libnpmversion/lib/write-json.js @@ -1,6 +1,5 @@ // write the json back, preserving the line breaks and indent -const { promisify } = require('util') -const writeFile = promisify(require('fs').writeFile) +const { writeFile } = require('fs/promises') const kIndent = Symbol.for('indent') const kNewline = Symbol.for('newline') diff --git a/deps/npm/node_modules/libnpmversion/package.json b/deps/npm/node_modules/libnpmversion/package.json index 782eeca7d2b795..43b0d2ff825d7b 100644 --- a/deps/npm/node_modules/libnpmversion/package.json +++ b/deps/npm/node_modules/libnpmversion/package.json @@ -1,6 +1,6 @@ { "name": "libnpmversion", - "version": "5.0.2", + "version": "6.0.1", "main": "lib/index.js", "files": [ "bin/", @@ -9,7 +9,7 @@ "description": "library to do the things that 'npm version' does", "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "workspaces/libnpmversion" }, "author": "GitHub Inc.", @@ -37,10 +37,10 @@ "tap": "^16.3.8" }, "dependencies": { - "@npmcli/git": "^5.0.3", - "@npmcli/run-script": "^7.0.2", + "@npmcli/git": "^5.0.6", + "@npmcli/run-script": "^8.1.0", "json-parse-even-better-errors": "^3.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.2.0", "semver": "^7.3.7" }, "engines": { diff --git a/deps/npm/node_modules/lru-cache/dist/commonjs/index.min.js b/deps/npm/node_modules/lru-cache/dist/commonjs/index.min.js new file mode 100644 index 00000000000000..b7149f5415a45f --- /dev/null +++ b/deps/npm/node_modules/lru-cache/dist/commonjs/index.min.js @@ -0,0 +1,2 @@ +"use strict";var G=(o,t,e)=>{if(!t.has(o))throw TypeError("Cannot "+e)};var j=(o,t,e)=>(G(o,t,"read from private field"),e?e.call(o):t.get(o)),I=(o,t,e)=>{if(t.has(o))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(o):t.set(o,e)},D=(o,t,e,i)=>(G(o,t,"write to private field"),i?i.call(o,e):t.set(o,e),e);Object.defineProperty(exports,"__esModule",{value:!0});exports.LRUCache=void 0;var T=typeof performance=="object"&&performance&&typeof performance.now=="function"?performance:Date,N=new Set,L=typeof process=="object"&&process?process:{},P=(o,t,e,i)=>{typeof L.emitWarning=="function"?L.emitWarning(o,t,e,i):console.error(`[${e}] ${t}: ${o}`)},W=globalThis.AbortController,M=globalThis.AbortSignal;if(typeof W>"u"){M=class{onabort;_onabort=[];reason;aborted=!1;addEventListener(i,s){this._onabort.push(s)}},W=class{constructor(){t()}signal=new M;abort(i){if(!this.signal.aborted){this.signal.reason=i,this.signal.aborted=!0;for(let s of this.signal._onabort)s(i);this.signal.onabort?.(i)}}};let o=L.env?.LRU_CACHE_IGNORE_AC_WARNING!=="1",t=()=>{o&&(o=!1,P("AbortController is not defined. If using lru-cache in node 14, load an AbortController polyfill from the `node-abort-controller` package. A minimal polyfill is provided for use by LRUCache.fetch(), but it should not be relied upon in other contexts (eg, passing it to other APIs that use AbortController/AbortSignal might have undesirable effects). You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.","NO_ABORT_CONTROLLER","ENOTSUP",t))}}var V=o=>!N.has(o),Y=Symbol("type"),A=o=>o&&o===Math.floor(o)&&o>0&&isFinite(o),H=o=>A(o)?o<=Math.pow(2,8)?Uint8Array:o<=Math.pow(2,16)?Uint16Array:o<=Math.pow(2,32)?Uint32Array:o<=Number.MAX_SAFE_INTEGER?E:null:null,E=class extends Array{constructor(t){super(t),this.fill(0)}},v,z=class{heap;length;static create(t){let e=H(t);if(!e)return[];D(z,v,!0);let i=new z(t,e);return D(z,v,!1),i}constructor(t,e){if(!j(z,v))throw new TypeError("instantiate Stack using Stack.create(n)");this.heap=new e(t),this.length=0}push(t){this.heap[this.length++]=t}pop(){return this.heap[--this.length]}},R=z;v=new WeakMap,I(R,v,!1);var C=class{#g;#f;#p;#w;#C;ttl;ttlResolution;ttlAutopurge;updateAgeOnGet;updateAgeOnHas;allowStale;noDisposeOnSet;noUpdateTTL;maxEntrySize;sizeCalculation;noDeleteOnFetchRejection;noDeleteOnStaleGet;allowStaleOnFetchAbort;allowStaleOnFetchRejection;ignoreFetchAbort;#n;#S;#s;#i;#t;#l;#c;#o;#h;#_;#r;#b;#y;#u;#m;#T;#a;static unsafeExposeInternals(t){return{starts:t.#y,ttls:t.#u,sizes:t.#b,keyMap:t.#s,keyList:t.#i,valList:t.#t,next:t.#l,prev:t.#c,get head(){return t.#o},get tail(){return t.#h},free:t.#_,isBackgroundFetch:e=>t.#e(e),backgroundFetch:(e,i,s,n)=>t.#D(e,i,s,n),moveToTail:e=>t.#v(e),indexes:e=>t.#A(e),rindexes:e=>t.#F(e),isStale:e=>t.#d(e)}}get max(){return this.#g}get maxSize(){return this.#f}get calculatedSize(){return this.#S}get size(){return this.#n}get fetchMethod(){return this.#C}get dispose(){return this.#p}get disposeAfter(){return this.#w}constructor(t){let{max:e=0,ttl:i,ttlResolution:s=1,ttlAutopurge:n,updateAgeOnGet:h,updateAgeOnHas:l,allowStale:r,dispose:g,disposeAfter:b,noDisposeOnSet:f,noUpdateTTL:u,maxSize:c=0,maxEntrySize:F=0,sizeCalculation:d,fetchMethod:S,noDeleteOnFetchRejection:a,noDeleteOnStaleGet:w,allowStaleOnFetchRejection:y,allowStaleOnFetchAbort:p,ignoreFetchAbort:_}=t;if(e!==0&&!A(e))throw new TypeError("max option must be a nonnegative integer");let O=e?H(e):Array;if(!O)throw new Error("invalid max value: "+e);if(this.#g=e,this.#f=c,this.maxEntrySize=F||this.#f,this.sizeCalculation=d,this.sizeCalculation){if(!this.#f&&!this.maxEntrySize)throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");if(typeof this.sizeCalculation!="function")throw new TypeError("sizeCalculation set to non-function")}if(S!==void 0&&typeof S!="function")throw new TypeError("fetchMethod must be a function if specified");if(this.#C=S,this.#T=!!S,this.#s=new Map,this.#i=new Array(e).fill(void 0),this.#t=new Array(e).fill(void 0),this.#l=new O(e),this.#c=new O(e),this.#o=0,this.#h=0,this.#_=R.create(e),this.#n=0,this.#S=0,typeof g=="function"&&(this.#p=g),typeof b=="function"?(this.#w=b,this.#r=[]):(this.#w=void 0,this.#r=void 0),this.#m=!!this.#p,this.#a=!!this.#w,this.noDisposeOnSet=!!f,this.noUpdateTTL=!!u,this.noDeleteOnFetchRejection=!!a,this.allowStaleOnFetchRejection=!!y,this.allowStaleOnFetchAbort=!!p,this.ignoreFetchAbort=!!_,this.maxEntrySize!==0){if(this.#f!==0&&!A(this.#f))throw new TypeError("maxSize must be a positive integer if specified");if(!A(this.maxEntrySize))throw new TypeError("maxEntrySize must be a positive integer if specified");this.#I()}if(this.allowStale=!!r,this.noDeleteOnStaleGet=!!w,this.updateAgeOnGet=!!h,this.updateAgeOnHas=!!l,this.ttlResolution=A(s)||s===0?s:1,this.ttlAutopurge=!!n,this.ttl=i||0,this.ttl){if(!A(this.ttl))throw new TypeError("ttl must be a positive integer if specified");this.#L()}if(this.#g===0&&this.ttl===0&&this.#f===0)throw new TypeError("At least one of max, maxSize, or ttl is required");if(!this.ttlAutopurge&&!this.#g&&!this.#f){let m="LRU_CACHE_UNBOUNDED";V(m)&&(N.add(m),P("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.","UnboundedCacheWarning",m,C))}}getRemainingTTL(t){return this.#s.has(t)?1/0:0}#L(){let t=new E(this.#g),e=new E(this.#g);this.#u=t,this.#y=e,this.#U=(n,h,l=T.now())=>{if(e[n]=h!==0?l:0,t[n]=h,h!==0&&this.ttlAutopurge){let r=setTimeout(()=>{this.#d(n)&&this.delete(this.#i[n])},h+1);r.unref&&r.unref()}},this.#z=n=>{e[n]=t[n]!==0?T.now():0},this.#O=(n,h)=>{if(t[h]){let l=t[h],r=e[h];if(!l||!r)return;n.ttl=l,n.start=r,n.now=i||s();let g=n.now-r;n.remainingTTL=l-g}};let i=0,s=()=>{let n=T.now();if(this.ttlResolution>0){i=n;let h=setTimeout(()=>i=0,this.ttlResolution);h.unref&&h.unref()}return n};this.getRemainingTTL=n=>{let h=this.#s.get(n);if(h===void 0)return 0;let l=t[h],r=e[h];if(!l||!r)return 1/0;let g=(i||s())-r;return l-g},this.#d=n=>{let h=e[n],l=t[n];return!!l&&!!h&&(i||s())-h>l}}#z=()=>{};#O=()=>{};#U=()=>{};#d=()=>!1;#I(){let t=new E(this.#g);this.#S=0,this.#b=t,this.#E=e=>{this.#S-=t[e],t[e]=0},this.#x=(e,i,s,n)=>{if(this.#e(i))return 0;if(!A(s))if(n){if(typeof n!="function")throw new TypeError("sizeCalculation must be a function");if(s=n(i,e),!A(s))throw new TypeError("sizeCalculation return invalid (expect positive integer)")}else throw new TypeError("invalid size value (must be positive integer). When maxSize or maxEntrySize is used, sizeCalculation or size must be set.");return s},this.#R=(e,i,s)=>{if(t[e]=i,this.#f){let n=this.#f-t[e];for(;this.#S>n;)this.#W(!0)}this.#S+=t[e],s&&(s.entrySize=i,s.totalCalculatedSize=this.#S)}}#E=t=>{};#R=(t,e,i)=>{};#x=(t,e,i,s)=>{if(i||s)throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");return 0};*#A({allowStale:t=this.allowStale}={}){if(this.#n)for(let e=this.#h;!(!this.#G(e)||((t||!this.#d(e))&&(yield e),e===this.#o));)e=this.#c[e]}*#F({allowStale:t=this.allowStale}={}){if(this.#n)for(let e=this.#o;!(!this.#G(e)||((t||!this.#d(e))&&(yield e),e===this.#h));)e=this.#l[e]}#G(t){return t!==void 0&&this.#s.get(this.#i[t])===t}*entries(){for(let t of this.#A())this.#t[t]!==void 0&&this.#i[t]!==void 0&&!this.#e(this.#t[t])&&(yield[this.#i[t],this.#t[t]])}*rentries(){for(let t of this.#F())this.#t[t]!==void 0&&this.#i[t]!==void 0&&!this.#e(this.#t[t])&&(yield[this.#i[t],this.#t[t]])}*keys(){for(let t of this.#A()){let e=this.#i[t];e!==void 0&&!this.#e(this.#t[t])&&(yield e)}}*rkeys(){for(let t of this.#F()){let e=this.#i[t];e!==void 0&&!this.#e(this.#t[t])&&(yield e)}}*values(){for(let t of this.#A())this.#t[t]!==void 0&&!this.#e(this.#t[t])&&(yield this.#t[t])}*rvalues(){for(let t of this.#F())this.#t[t]!==void 0&&!this.#e(this.#t[t])&&(yield this.#t[t])}[Symbol.iterator](){return this.entries()}[Symbol.toStringTag]="LRUCache";find(t,e={}){for(let i of this.#A()){let s=this.#t[i],n=this.#e(s)?s.__staleWhileFetching:s;if(n!==void 0&&t(n,this.#i[i],this))return this.get(this.#i[i],e)}}forEach(t,e=this){for(let i of this.#A()){let s=this.#t[i],n=this.#e(s)?s.__staleWhileFetching:s;n!==void 0&&t.call(e,n,this.#i[i],this)}}rforEach(t,e=this){for(let i of this.#F()){let s=this.#t[i],n=this.#e(s)?s.__staleWhileFetching:s;n!==void 0&&t.call(e,n,this.#i[i],this)}}purgeStale(){let t=!1;for(let e of this.#F({allowStale:!0}))this.#d(e)&&(this.delete(this.#i[e]),t=!0);return t}info(t){let e=this.#s.get(t);if(e===void 0)return;let i=this.#t[e],s=this.#e(i)?i.__staleWhileFetching:i;if(s===void 0)return;let n={value:s};if(this.#u&&this.#y){let h=this.#u[e],l=this.#y[e];if(h&&l){let r=h-(T.now()-l);n.ttl=r,n.start=Date.now()}}return this.#b&&(n.size=this.#b[e]),n}dump(){let t=[];for(let e of this.#A({allowStale:!0})){let i=this.#i[e],s=this.#t[e],n=this.#e(s)?s.__staleWhileFetching:s;if(n===void 0||i===void 0)continue;let h={value:n};if(this.#u&&this.#y){h.ttl=this.#u[e];let l=T.now()-this.#y[e];h.start=Math.floor(Date.now()-l)}this.#b&&(h.size=this.#b[e]),t.unshift([i,h])}return t}load(t){this.clear();for(let[e,i]of t){if(i.start){let s=Date.now()-i.start;i.start=T.now()-s}this.set(e,i.value,i)}}set(t,e,i={}){if(e===void 0)return this.delete(t),this;let{ttl:s=this.ttl,start:n,noDisposeOnSet:h=this.noDisposeOnSet,sizeCalculation:l=this.sizeCalculation,status:r}=i,{noUpdateTTL:g=this.noUpdateTTL}=i,b=this.#x(t,e,i.size||0,l);if(this.maxEntrySize&&b>this.maxEntrySize)return r&&(r.set="miss",r.maxEntrySizeExceeded=!0),this.delete(t),this;let f=this.#n===0?void 0:this.#s.get(t);if(f===void 0)f=this.#n===0?this.#h:this.#_.length!==0?this.#_.pop():this.#n===this.#g?this.#W(!1):this.#n,this.#i[f]=t,this.#t[f]=e,this.#s.set(t,f),this.#l[this.#h]=f,this.#c[f]=this.#h,this.#h=f,this.#n++,this.#R(f,b,r),r&&(r.set="add"),g=!1;else{this.#v(f);let u=this.#t[f];if(e!==u){if(this.#T&&this.#e(u)){u.__abortController.abort(new Error("replaced"));let{__staleWhileFetching:c}=u;c!==void 0&&!h&&(this.#m&&this.#p?.(c,t,"set"),this.#a&&this.#r?.push([c,t,"set"]))}else h||(this.#m&&this.#p?.(u,t,"set"),this.#a&&this.#r?.push([u,t,"set"]));if(this.#E(f),this.#R(f,b,r),this.#t[f]=e,r){r.set="replace";let c=u&&this.#e(u)?u.__staleWhileFetching:u;c!==void 0&&(r.oldValue=c)}}else r&&(r.set="update")}if(s!==0&&!this.#u&&this.#L(),this.#u&&(g||this.#U(f,s,n),r&&this.#O(r,f)),!h&&this.#a&&this.#r){let u=this.#r,c;for(;c=u?.shift();)this.#w?.(...c)}return this}pop(){try{for(;this.#n;){let t=this.#t[this.#o];if(this.#W(!0),this.#e(t)){if(t.__staleWhileFetching)return t.__staleWhileFetching}else if(t!==void 0)return t}}finally{if(this.#a&&this.#r){let t=this.#r,e;for(;e=t?.shift();)this.#w?.(...e)}}}#W(t){let e=this.#o,i=this.#i[e],s=this.#t[e];return this.#T&&this.#e(s)?s.__abortController.abort(new Error("evicted")):(this.#m||this.#a)&&(this.#m&&this.#p?.(s,i,"evict"),this.#a&&this.#r?.push([s,i,"evict"])),this.#E(e),t&&(this.#i[e]=void 0,this.#t[e]=void 0,this.#_.push(e)),this.#n===1?(this.#o=this.#h=0,this.#_.length=0):this.#o=this.#l[e],this.#s.delete(i),this.#n--,e}has(t,e={}){let{updateAgeOnHas:i=this.updateAgeOnHas,status:s}=e,n=this.#s.get(t);if(n!==void 0){let h=this.#t[n];if(this.#e(h)&&h.__staleWhileFetching===void 0)return!1;if(this.#d(n))s&&(s.has="stale",this.#O(s,n));else return i&&this.#z(n),s&&(s.has="hit",this.#O(s,n)),!0}else s&&(s.has="miss");return!1}peek(t,e={}){let{allowStale:i=this.allowStale}=e,s=this.#s.get(t);if(s===void 0||!i&&this.#d(s))return;let n=this.#t[s];return this.#e(n)?n.__staleWhileFetching:n}#D(t,e,i,s){let n=e===void 0?void 0:this.#t[e];if(this.#e(n))return n;let h=new W,{signal:l}=i;l?.addEventListener("abort",()=>h.abort(l.reason),{signal:h.signal});let r={signal:h.signal,options:i,context:s},g=(d,S=!1)=>{let{aborted:a}=h.signal,w=i.ignoreFetchAbort&&d!==void 0;if(i.status&&(a&&!S?(i.status.fetchAborted=!0,i.status.fetchError=h.signal.reason,w&&(i.status.fetchAbortIgnored=!0)):i.status.fetchResolved=!0),a&&!w&&!S)return f(h.signal.reason);let y=c;return this.#t[e]===c&&(d===void 0?y.__staleWhileFetching?this.#t[e]=y.__staleWhileFetching:this.delete(t):(i.status&&(i.status.fetchUpdated=!0),this.set(t,d,r.options))),d},b=d=>(i.status&&(i.status.fetchRejected=!0,i.status.fetchError=d),f(d)),f=d=>{let{aborted:S}=h.signal,a=S&&i.allowStaleOnFetchAbort,w=a||i.allowStaleOnFetchRejection,y=w||i.noDeleteOnFetchRejection,p=c;if(this.#t[e]===c&&(!y||p.__staleWhileFetching===void 0?this.delete(t):a||(this.#t[e]=p.__staleWhileFetching)),w)return i.status&&p.__staleWhileFetching!==void 0&&(i.status.returnedStale=!0),p.__staleWhileFetching;if(p.__returned===p)throw d},u=(d,S)=>{let a=this.#C?.(t,n,r);a&&a instanceof Promise&&a.then(w=>d(w===void 0?void 0:w),S),h.signal.addEventListener("abort",()=>{(!i.ignoreFetchAbort||i.allowStaleOnFetchAbort)&&(d(void 0),i.allowStaleOnFetchAbort&&(d=w=>g(w,!0)))})};i.status&&(i.status.fetchDispatched=!0);let c=new Promise(u).then(g,b),F=Object.assign(c,{__abortController:h,__staleWhileFetching:n,__returned:void 0});return e===void 0?(this.set(t,F,{...r.options,status:void 0}),e=this.#s.get(t)):this.#t[e]=F,F}#e(t){if(!this.#T)return!1;let e=t;return!!e&&e instanceof Promise&&e.hasOwnProperty("__staleWhileFetching")&&e.__abortController instanceof W}async fetch(t,e={}){let{allowStale:i=this.allowStale,updateAgeOnGet:s=this.updateAgeOnGet,noDeleteOnStaleGet:n=this.noDeleteOnStaleGet,ttl:h=this.ttl,noDisposeOnSet:l=this.noDisposeOnSet,size:r=0,sizeCalculation:g=this.sizeCalculation,noUpdateTTL:b=this.noUpdateTTL,noDeleteOnFetchRejection:f=this.noDeleteOnFetchRejection,allowStaleOnFetchRejection:u=this.allowStaleOnFetchRejection,ignoreFetchAbort:c=this.ignoreFetchAbort,allowStaleOnFetchAbort:F=this.allowStaleOnFetchAbort,context:d,forceRefresh:S=!1,status:a,signal:w}=e;if(!this.#T)return a&&(a.fetch="get"),this.get(t,{allowStale:i,updateAgeOnGet:s,noDeleteOnStaleGet:n,status:a});let y={allowStale:i,updateAgeOnGet:s,noDeleteOnStaleGet:n,ttl:h,noDisposeOnSet:l,size:r,sizeCalculation:g,noUpdateTTL:b,noDeleteOnFetchRejection:f,allowStaleOnFetchRejection:u,allowStaleOnFetchAbort:F,ignoreFetchAbort:c,status:a,signal:w},p=this.#s.get(t);if(p===void 0){a&&(a.fetch="miss");let _=this.#D(t,p,y,d);return _.__returned=_}else{let _=this.#t[p];if(this.#e(_)){let x=i&&_.__staleWhileFetching!==void 0;return a&&(a.fetch="inflight",x&&(a.returnedStale=!0)),x?_.__staleWhileFetching:_.__returned=_}let O=this.#d(p);if(!S&&!O)return a&&(a.fetch="hit"),this.#v(p),s&&this.#z(p),a&&this.#O(a,p),_;let m=this.#D(t,p,y,d),U=m.__staleWhileFetching!==void 0&&i;return a&&(a.fetch=O?"stale":"refresh",U&&O&&(a.returnedStale=!0)),U?m.__staleWhileFetching:m.__returned=m}}get(t,e={}){let{allowStale:i=this.allowStale,updateAgeOnGet:s=this.updateAgeOnGet,noDeleteOnStaleGet:n=this.noDeleteOnStaleGet,status:h}=e,l=this.#s.get(t);if(l!==void 0){let r=this.#t[l],g=this.#e(r);return h&&this.#O(h,l),this.#d(l)?(h&&(h.get="stale"),g?(h&&i&&r.__staleWhileFetching!==void 0&&(h.returnedStale=!0),i?r.__staleWhileFetching:void 0):(n||this.delete(t),h&&i&&(h.returnedStale=!0),i?r:void 0)):(h&&(h.get="hit"),g?r.__staleWhileFetching:(this.#v(l),s&&this.#z(l),r))}else h&&(h.get="miss")}#j(t,e){this.#c[e]=t,this.#l[t]=e}#v(t){t!==this.#h&&(t===this.#o?this.#o=this.#l[t]:this.#j(this.#c[t],this.#l[t]),this.#j(this.#h,t),this.#h=t)}delete(t){let e=!1;if(this.#n!==0){let i=this.#s.get(t);if(i!==void 0)if(e=!0,this.#n===1)this.clear();else{this.#E(i);let s=this.#t[i];if(this.#e(s)?s.__abortController.abort(new Error("deleted")):(this.#m||this.#a)&&(this.#m&&this.#p?.(s,t,"delete"),this.#a&&this.#r?.push([s,t,"delete"])),this.#s.delete(t),this.#i[i]=void 0,this.#t[i]=void 0,i===this.#h)this.#h=this.#c[i];else if(i===this.#o)this.#o=this.#l[i];else{let n=this.#c[i];this.#l[n]=this.#l[i];let h=this.#l[i];this.#c[h]=this.#c[i]}this.#n--,this.#_.push(i)}}if(this.#a&&this.#r?.length){let i=this.#r,s;for(;s=i?.shift();)this.#w?.(...s)}return e}clear(){for(let t of this.#F({allowStale:!0})){let e=this.#t[t];if(this.#e(e))e.__abortController.abort(new Error("deleted"));else{let i=this.#i[t];this.#m&&this.#p?.(e,i,"delete"),this.#a&&this.#r?.push([e,i,"delete"])}}if(this.#s.clear(),this.#t.fill(void 0),this.#i.fill(void 0),this.#u&&this.#y&&(this.#u.fill(0),this.#y.fill(0)),this.#b&&this.#b.fill(0),this.#o=0,this.#h=0,this.#_.length=0,this.#S=0,this.#n=0,this.#a&&this.#r){let t=this.#r,e;for(;e=t?.shift();)this.#w?.(...e)}}};exports.LRUCache=C; +//# sourceMappingURL=index.min.js.map diff --git a/deps/npm/node_modules/lru-cache/dist/esm/index.min.js b/deps/npm/node_modules/lru-cache/dist/esm/index.min.js new file mode 100644 index 00000000000000..4285815f9abb17 --- /dev/null +++ b/deps/npm/node_modules/lru-cache/dist/esm/index.min.js @@ -0,0 +1,2 @@ +var G=(o,t,e)=>{if(!t.has(o))throw TypeError("Cannot "+e)};var I=(o,t,e)=>(G(o,t,"read from private field"),e?e.call(o):t.get(o)),j=(o,t,e)=>{if(t.has(o))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(o):t.set(o,e)},D=(o,t,e,i)=>(G(o,t,"write to private field"),i?i.call(o,e):t.set(o,e),e);var O=typeof performance=="object"&&performance&&typeof performance.now=="function"?performance:Date,M=new Set,L=typeof process=="object"&&process?process:{},P=(o,t,e,i)=>{typeof L.emitWarning=="function"?L.emitWarning(o,t,e,i):console.error(`[${e}] ${t}: ${o}`)},W=globalThis.AbortController,N=globalThis.AbortSignal;if(typeof W>"u"){N=class{onabort;_onabort=[];reason;aborted=!1;addEventListener(i,s){this._onabort.push(s)}},W=class{constructor(){t()}signal=new N;abort(i){if(!this.signal.aborted){this.signal.reason=i,this.signal.aborted=!0;for(let s of this.signal._onabort)s(i);this.signal.onabort?.(i)}}};let o=L.env?.LRU_CACHE_IGNORE_AC_WARNING!=="1",t=()=>{o&&(o=!1,P("AbortController is not defined. If using lru-cache in node 14, load an AbortController polyfill from the `node-abort-controller` package. A minimal polyfill is provided for use by LRUCache.fetch(), but it should not be relied upon in other contexts (eg, passing it to other APIs that use AbortController/AbortSignal might have undesirable effects). You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.","NO_ABORT_CONTROLLER","ENOTSUP",t))}}var V=o=>!M.has(o),Y=Symbol("type"),A=o=>o&&o===Math.floor(o)&&o>0&&isFinite(o),H=o=>A(o)?o<=Math.pow(2,8)?Uint8Array:o<=Math.pow(2,16)?Uint16Array:o<=Math.pow(2,32)?Uint32Array:o<=Number.MAX_SAFE_INTEGER?E:null:null,E=class extends Array{constructor(t){super(t),this.fill(0)}},v,z=class{heap;length;static create(t){let e=H(t);if(!e)return[];D(z,v,!0);let i=new z(t,e);return D(z,v,!1),i}constructor(t,e){if(!I(z,v))throw new TypeError("instantiate Stack using Stack.create(n)");this.heap=new e(t),this.length=0}push(t){this.heap[this.length++]=t}pop(){return this.heap[--this.length]}},C=z;v=new WeakMap,j(C,v,!1);var R=class{#g;#f;#p;#w;#C;ttl;ttlResolution;ttlAutopurge;updateAgeOnGet;updateAgeOnHas;allowStale;noDisposeOnSet;noUpdateTTL;maxEntrySize;sizeCalculation;noDeleteOnFetchRejection;noDeleteOnStaleGet;allowStaleOnFetchAbort;allowStaleOnFetchRejection;ignoreFetchAbort;#n;#S;#s;#i;#t;#l;#c;#o;#h;#_;#r;#b;#y;#u;#m;#O;#a;static unsafeExposeInternals(t){return{starts:t.#y,ttls:t.#u,sizes:t.#b,keyMap:t.#s,keyList:t.#i,valList:t.#t,next:t.#l,prev:t.#c,get head(){return t.#o},get tail(){return t.#h},free:t.#_,isBackgroundFetch:e=>t.#e(e),backgroundFetch:(e,i,s,n)=>t.#D(e,i,s,n),moveToTail:e=>t.#v(e),indexes:e=>t.#A(e),rindexes:e=>t.#F(e),isStale:e=>t.#d(e)}}get max(){return this.#g}get maxSize(){return this.#f}get calculatedSize(){return this.#S}get size(){return this.#n}get fetchMethod(){return this.#C}get dispose(){return this.#p}get disposeAfter(){return this.#w}constructor(t){let{max:e=0,ttl:i,ttlResolution:s=1,ttlAutopurge:n,updateAgeOnGet:h,updateAgeOnHas:l,allowStale:r,dispose:g,disposeAfter:b,noDisposeOnSet:f,noUpdateTTL:u,maxSize:c=0,maxEntrySize:F=0,sizeCalculation:d,fetchMethod:S,noDeleteOnFetchRejection:a,noDeleteOnStaleGet:w,allowStaleOnFetchRejection:y,allowStaleOnFetchAbort:p,ignoreFetchAbort:_}=t;if(e!==0&&!A(e))throw new TypeError("max option must be a nonnegative integer");let T=e?H(e):Array;if(!T)throw new Error("invalid max value: "+e);if(this.#g=e,this.#f=c,this.maxEntrySize=F||this.#f,this.sizeCalculation=d,this.sizeCalculation){if(!this.#f&&!this.maxEntrySize)throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");if(typeof this.sizeCalculation!="function")throw new TypeError("sizeCalculation set to non-function")}if(S!==void 0&&typeof S!="function")throw new TypeError("fetchMethod must be a function if specified");if(this.#C=S,this.#O=!!S,this.#s=new Map,this.#i=new Array(e).fill(void 0),this.#t=new Array(e).fill(void 0),this.#l=new T(e),this.#c=new T(e),this.#o=0,this.#h=0,this.#_=C.create(e),this.#n=0,this.#S=0,typeof g=="function"&&(this.#p=g),typeof b=="function"?(this.#w=b,this.#r=[]):(this.#w=void 0,this.#r=void 0),this.#m=!!this.#p,this.#a=!!this.#w,this.noDisposeOnSet=!!f,this.noUpdateTTL=!!u,this.noDeleteOnFetchRejection=!!a,this.allowStaleOnFetchRejection=!!y,this.allowStaleOnFetchAbort=!!p,this.ignoreFetchAbort=!!_,this.maxEntrySize!==0){if(this.#f!==0&&!A(this.#f))throw new TypeError("maxSize must be a positive integer if specified");if(!A(this.maxEntrySize))throw new TypeError("maxEntrySize must be a positive integer if specified");this.#j()}if(this.allowStale=!!r,this.noDeleteOnStaleGet=!!w,this.updateAgeOnGet=!!h,this.updateAgeOnHas=!!l,this.ttlResolution=A(s)||s===0?s:1,this.ttlAutopurge=!!n,this.ttl=i||0,this.ttl){if(!A(this.ttl))throw new TypeError("ttl must be a positive integer if specified");this.#L()}if(this.#g===0&&this.ttl===0&&this.#f===0)throw new TypeError("At least one of max, maxSize, or ttl is required");if(!this.ttlAutopurge&&!this.#g&&!this.#f){let m="LRU_CACHE_UNBOUNDED";V(m)&&(M.add(m),P("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.","UnboundedCacheWarning",m,R))}}getRemainingTTL(t){return this.#s.has(t)?1/0:0}#L(){let t=new E(this.#g),e=new E(this.#g);this.#u=t,this.#y=e,this.#x=(n,h,l=O.now())=>{if(e[n]=h!==0?l:0,t[n]=h,h!==0&&this.ttlAutopurge){let r=setTimeout(()=>{this.#d(n)&&this.delete(this.#i[n])},h+1);r.unref&&r.unref()}},this.#z=n=>{e[n]=t[n]!==0?O.now():0},this.#T=(n,h)=>{if(t[h]){let l=t[h],r=e[h];if(!l||!r)return;n.ttl=l,n.start=r,n.now=i||s();let g=n.now-r;n.remainingTTL=l-g}};let i=0,s=()=>{let n=O.now();if(this.ttlResolution>0){i=n;let h=setTimeout(()=>i=0,this.ttlResolution);h.unref&&h.unref()}return n};this.getRemainingTTL=n=>{let h=this.#s.get(n);if(h===void 0)return 0;let l=t[h],r=e[h];if(!l||!r)return 1/0;let g=(i||s())-r;return l-g},this.#d=n=>{let h=e[n],l=t[n];return!!l&&!!h&&(i||s())-h>l}}#z=()=>{};#T=()=>{};#x=()=>{};#d=()=>!1;#j(){let t=new E(this.#g);this.#S=0,this.#b=t,this.#E=e=>{this.#S-=t[e],t[e]=0},this.#U=(e,i,s,n)=>{if(this.#e(i))return 0;if(!A(s))if(n){if(typeof n!="function")throw new TypeError("sizeCalculation must be a function");if(s=n(i,e),!A(s))throw new TypeError("sizeCalculation return invalid (expect positive integer)")}else throw new TypeError("invalid size value (must be positive integer). When maxSize or maxEntrySize is used, sizeCalculation or size must be set.");return s},this.#W=(e,i,s)=>{if(t[e]=i,this.#f){let n=this.#f-t[e];for(;this.#S>n;)this.#R(!0)}this.#S+=t[e],s&&(s.entrySize=i,s.totalCalculatedSize=this.#S)}}#E=t=>{};#W=(t,e,i)=>{};#U=(t,e,i,s)=>{if(i||s)throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");return 0};*#A({allowStale:t=this.allowStale}={}){if(this.#n)for(let e=this.#h;!(!this.#G(e)||((t||!this.#d(e))&&(yield e),e===this.#o));)e=this.#c[e]}*#F({allowStale:t=this.allowStale}={}){if(this.#n)for(let e=this.#o;!(!this.#G(e)||((t||!this.#d(e))&&(yield e),e===this.#h));)e=this.#l[e]}#G(t){return t!==void 0&&this.#s.get(this.#i[t])===t}*entries(){for(let t of this.#A())this.#t[t]!==void 0&&this.#i[t]!==void 0&&!this.#e(this.#t[t])&&(yield[this.#i[t],this.#t[t]])}*rentries(){for(let t of this.#F())this.#t[t]!==void 0&&this.#i[t]!==void 0&&!this.#e(this.#t[t])&&(yield[this.#i[t],this.#t[t]])}*keys(){for(let t of this.#A()){let e=this.#i[t];e!==void 0&&!this.#e(this.#t[t])&&(yield e)}}*rkeys(){for(let t of this.#F()){let e=this.#i[t];e!==void 0&&!this.#e(this.#t[t])&&(yield e)}}*values(){for(let t of this.#A())this.#t[t]!==void 0&&!this.#e(this.#t[t])&&(yield this.#t[t])}*rvalues(){for(let t of this.#F())this.#t[t]!==void 0&&!this.#e(this.#t[t])&&(yield this.#t[t])}[Symbol.iterator](){return this.entries()}[Symbol.toStringTag]="LRUCache";find(t,e={}){for(let i of this.#A()){let s=this.#t[i],n=this.#e(s)?s.__staleWhileFetching:s;if(n!==void 0&&t(n,this.#i[i],this))return this.get(this.#i[i],e)}}forEach(t,e=this){for(let i of this.#A()){let s=this.#t[i],n=this.#e(s)?s.__staleWhileFetching:s;n!==void 0&&t.call(e,n,this.#i[i],this)}}rforEach(t,e=this){for(let i of this.#F()){let s=this.#t[i],n=this.#e(s)?s.__staleWhileFetching:s;n!==void 0&&t.call(e,n,this.#i[i],this)}}purgeStale(){let t=!1;for(let e of this.#F({allowStale:!0}))this.#d(e)&&(this.delete(this.#i[e]),t=!0);return t}info(t){let e=this.#s.get(t);if(e===void 0)return;let i=this.#t[e],s=this.#e(i)?i.__staleWhileFetching:i;if(s===void 0)return;let n={value:s};if(this.#u&&this.#y){let h=this.#u[e],l=this.#y[e];if(h&&l){let r=h-(O.now()-l);n.ttl=r,n.start=Date.now()}}return this.#b&&(n.size=this.#b[e]),n}dump(){let t=[];for(let e of this.#A({allowStale:!0})){let i=this.#i[e],s=this.#t[e],n=this.#e(s)?s.__staleWhileFetching:s;if(n===void 0||i===void 0)continue;let h={value:n};if(this.#u&&this.#y){h.ttl=this.#u[e];let l=O.now()-this.#y[e];h.start=Math.floor(Date.now()-l)}this.#b&&(h.size=this.#b[e]),t.unshift([i,h])}return t}load(t){this.clear();for(let[e,i]of t){if(i.start){let s=Date.now()-i.start;i.start=O.now()-s}this.set(e,i.value,i)}}set(t,e,i={}){if(e===void 0)return this.delete(t),this;let{ttl:s=this.ttl,start:n,noDisposeOnSet:h=this.noDisposeOnSet,sizeCalculation:l=this.sizeCalculation,status:r}=i,{noUpdateTTL:g=this.noUpdateTTL}=i,b=this.#U(t,e,i.size||0,l);if(this.maxEntrySize&&b>this.maxEntrySize)return r&&(r.set="miss",r.maxEntrySizeExceeded=!0),this.delete(t),this;let f=this.#n===0?void 0:this.#s.get(t);if(f===void 0)f=this.#n===0?this.#h:this.#_.length!==0?this.#_.pop():this.#n===this.#g?this.#R(!1):this.#n,this.#i[f]=t,this.#t[f]=e,this.#s.set(t,f),this.#l[this.#h]=f,this.#c[f]=this.#h,this.#h=f,this.#n++,this.#W(f,b,r),r&&(r.set="add"),g=!1;else{this.#v(f);let u=this.#t[f];if(e!==u){if(this.#O&&this.#e(u)){u.__abortController.abort(new Error("replaced"));let{__staleWhileFetching:c}=u;c!==void 0&&!h&&(this.#m&&this.#p?.(c,t,"set"),this.#a&&this.#r?.push([c,t,"set"]))}else h||(this.#m&&this.#p?.(u,t,"set"),this.#a&&this.#r?.push([u,t,"set"]));if(this.#E(f),this.#W(f,b,r),this.#t[f]=e,r){r.set="replace";let c=u&&this.#e(u)?u.__staleWhileFetching:u;c!==void 0&&(r.oldValue=c)}}else r&&(r.set="update")}if(s!==0&&!this.#u&&this.#L(),this.#u&&(g||this.#x(f,s,n),r&&this.#T(r,f)),!h&&this.#a&&this.#r){let u=this.#r,c;for(;c=u?.shift();)this.#w?.(...c)}return this}pop(){try{for(;this.#n;){let t=this.#t[this.#o];if(this.#R(!0),this.#e(t)){if(t.__staleWhileFetching)return t.__staleWhileFetching}else if(t!==void 0)return t}}finally{if(this.#a&&this.#r){let t=this.#r,e;for(;e=t?.shift();)this.#w?.(...e)}}}#R(t){let e=this.#o,i=this.#i[e],s=this.#t[e];return this.#O&&this.#e(s)?s.__abortController.abort(new Error("evicted")):(this.#m||this.#a)&&(this.#m&&this.#p?.(s,i,"evict"),this.#a&&this.#r?.push([s,i,"evict"])),this.#E(e),t&&(this.#i[e]=void 0,this.#t[e]=void 0,this.#_.push(e)),this.#n===1?(this.#o=this.#h=0,this.#_.length=0):this.#o=this.#l[e],this.#s.delete(i),this.#n--,e}has(t,e={}){let{updateAgeOnHas:i=this.updateAgeOnHas,status:s}=e,n=this.#s.get(t);if(n!==void 0){let h=this.#t[n];if(this.#e(h)&&h.__staleWhileFetching===void 0)return!1;if(this.#d(n))s&&(s.has="stale",this.#T(s,n));else return i&&this.#z(n),s&&(s.has="hit",this.#T(s,n)),!0}else s&&(s.has="miss");return!1}peek(t,e={}){let{allowStale:i=this.allowStale}=e,s=this.#s.get(t);if(s===void 0||!i&&this.#d(s))return;let n=this.#t[s];return this.#e(n)?n.__staleWhileFetching:n}#D(t,e,i,s){let n=e===void 0?void 0:this.#t[e];if(this.#e(n))return n;let h=new W,{signal:l}=i;l?.addEventListener("abort",()=>h.abort(l.reason),{signal:h.signal});let r={signal:h.signal,options:i,context:s},g=(d,S=!1)=>{let{aborted:a}=h.signal,w=i.ignoreFetchAbort&&d!==void 0;if(i.status&&(a&&!S?(i.status.fetchAborted=!0,i.status.fetchError=h.signal.reason,w&&(i.status.fetchAbortIgnored=!0)):i.status.fetchResolved=!0),a&&!w&&!S)return f(h.signal.reason);let y=c;return this.#t[e]===c&&(d===void 0?y.__staleWhileFetching?this.#t[e]=y.__staleWhileFetching:this.delete(t):(i.status&&(i.status.fetchUpdated=!0),this.set(t,d,r.options))),d},b=d=>(i.status&&(i.status.fetchRejected=!0,i.status.fetchError=d),f(d)),f=d=>{let{aborted:S}=h.signal,a=S&&i.allowStaleOnFetchAbort,w=a||i.allowStaleOnFetchRejection,y=w||i.noDeleteOnFetchRejection,p=c;if(this.#t[e]===c&&(!y||p.__staleWhileFetching===void 0?this.delete(t):a||(this.#t[e]=p.__staleWhileFetching)),w)return i.status&&p.__staleWhileFetching!==void 0&&(i.status.returnedStale=!0),p.__staleWhileFetching;if(p.__returned===p)throw d},u=(d,S)=>{let a=this.#C?.(t,n,r);a&&a instanceof Promise&&a.then(w=>d(w===void 0?void 0:w),S),h.signal.addEventListener("abort",()=>{(!i.ignoreFetchAbort||i.allowStaleOnFetchAbort)&&(d(void 0),i.allowStaleOnFetchAbort&&(d=w=>g(w,!0)))})};i.status&&(i.status.fetchDispatched=!0);let c=new Promise(u).then(g,b),F=Object.assign(c,{__abortController:h,__staleWhileFetching:n,__returned:void 0});return e===void 0?(this.set(t,F,{...r.options,status:void 0}),e=this.#s.get(t)):this.#t[e]=F,F}#e(t){if(!this.#O)return!1;let e=t;return!!e&&e instanceof Promise&&e.hasOwnProperty("__staleWhileFetching")&&e.__abortController instanceof W}async fetch(t,e={}){let{allowStale:i=this.allowStale,updateAgeOnGet:s=this.updateAgeOnGet,noDeleteOnStaleGet:n=this.noDeleteOnStaleGet,ttl:h=this.ttl,noDisposeOnSet:l=this.noDisposeOnSet,size:r=0,sizeCalculation:g=this.sizeCalculation,noUpdateTTL:b=this.noUpdateTTL,noDeleteOnFetchRejection:f=this.noDeleteOnFetchRejection,allowStaleOnFetchRejection:u=this.allowStaleOnFetchRejection,ignoreFetchAbort:c=this.ignoreFetchAbort,allowStaleOnFetchAbort:F=this.allowStaleOnFetchAbort,context:d,forceRefresh:S=!1,status:a,signal:w}=e;if(!this.#O)return a&&(a.fetch="get"),this.get(t,{allowStale:i,updateAgeOnGet:s,noDeleteOnStaleGet:n,status:a});let y={allowStale:i,updateAgeOnGet:s,noDeleteOnStaleGet:n,ttl:h,noDisposeOnSet:l,size:r,sizeCalculation:g,noUpdateTTL:b,noDeleteOnFetchRejection:f,allowStaleOnFetchRejection:u,allowStaleOnFetchAbort:F,ignoreFetchAbort:c,status:a,signal:w},p=this.#s.get(t);if(p===void 0){a&&(a.fetch="miss");let _=this.#D(t,p,y,d);return _.__returned=_}else{let _=this.#t[p];if(this.#e(_)){let U=i&&_.__staleWhileFetching!==void 0;return a&&(a.fetch="inflight",U&&(a.returnedStale=!0)),U?_.__staleWhileFetching:_.__returned=_}let T=this.#d(p);if(!S&&!T)return a&&(a.fetch="hit"),this.#v(p),s&&this.#z(p),a&&this.#T(a,p),_;let m=this.#D(t,p,y,d),x=m.__staleWhileFetching!==void 0&&i;return a&&(a.fetch=T?"stale":"refresh",x&&T&&(a.returnedStale=!0)),x?m.__staleWhileFetching:m.__returned=m}}get(t,e={}){let{allowStale:i=this.allowStale,updateAgeOnGet:s=this.updateAgeOnGet,noDeleteOnStaleGet:n=this.noDeleteOnStaleGet,status:h}=e,l=this.#s.get(t);if(l!==void 0){let r=this.#t[l],g=this.#e(r);return h&&this.#T(h,l),this.#d(l)?(h&&(h.get="stale"),g?(h&&i&&r.__staleWhileFetching!==void 0&&(h.returnedStale=!0),i?r.__staleWhileFetching:void 0):(n||this.delete(t),h&&i&&(h.returnedStale=!0),i?r:void 0)):(h&&(h.get="hit"),g?r.__staleWhileFetching:(this.#v(l),s&&this.#z(l),r))}else h&&(h.get="miss")}#I(t,e){this.#c[e]=t,this.#l[t]=e}#v(t){t!==this.#h&&(t===this.#o?this.#o=this.#l[t]:this.#I(this.#c[t],this.#l[t]),this.#I(this.#h,t),this.#h=t)}delete(t){let e=!1;if(this.#n!==0){let i=this.#s.get(t);if(i!==void 0)if(e=!0,this.#n===1)this.clear();else{this.#E(i);let s=this.#t[i];if(this.#e(s)?s.__abortController.abort(new Error("deleted")):(this.#m||this.#a)&&(this.#m&&this.#p?.(s,t,"delete"),this.#a&&this.#r?.push([s,t,"delete"])),this.#s.delete(t),this.#i[i]=void 0,this.#t[i]=void 0,i===this.#h)this.#h=this.#c[i];else if(i===this.#o)this.#o=this.#l[i];else{let n=this.#c[i];this.#l[n]=this.#l[i];let h=this.#l[i];this.#c[h]=this.#c[i]}this.#n--,this.#_.push(i)}}if(this.#a&&this.#r?.length){let i=this.#r,s;for(;s=i?.shift();)this.#w?.(...s)}return e}clear(){for(let t of this.#F({allowStale:!0})){let e=this.#t[t];if(this.#e(e))e.__abortController.abort(new Error("deleted"));else{let i=this.#i[t];this.#m&&this.#p?.(e,i,"delete"),this.#a&&this.#r?.push([e,i,"delete"])}}if(this.#s.clear(),this.#t.fill(void 0),this.#i.fill(void 0),this.#u&&this.#y&&(this.#u.fill(0),this.#y.fill(0)),this.#b&&this.#b.fill(0),this.#o=0,this.#h=0,this.#_.length=0,this.#S=0,this.#n=0,this.#a&&this.#r){let t=this.#r,e;for(;e=t?.shift();)this.#w?.(...e)}}};export{R as LRUCache}; +//# sourceMappingURL=index.min.js.map diff --git a/deps/npm/node_modules/lru-cache/package.json b/deps/npm/node_modules/lru-cache/package.json index 348e2118a7c25c..ef118623196112 100644 --- a/deps/npm/node_modules/lru-cache/package.json +++ b/deps/npm/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": "10.2.0", + "version": "10.2.2", "author": "Isaac Z. Schlueter ", "keywords": [ "mru", @@ -11,8 +11,7 @@ "sideEffects": false, "scripts": { "build": "npm run prepare", - "prepare": "tshy", - "postprepare": "bash fixup.sh", + "prepare": "tshy && bash fixup.sh", "pretest": "npm run prepare", "presnap": "npm run prepare", "test": "tap", @@ -35,8 +34,8 @@ ".": "./src/index.ts", "./min": { "import": { - "types": "./dist/mjs/index.d.ts", - "default": "./dist/mjs/index.min.js" + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.min.js" }, "require": { "types": "./dist/commonjs/index.d.ts", @@ -105,8 +104,8 @@ }, "./min": { "import": { - "types": "./dist/mjs/index.d.ts", - "default": "./dist/mjs/index.min.js" + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.min.js" }, "require": { "types": "./dist/commonjs/index.d.ts", diff --git a/deps/npm/node_modules/make-fetch-happen/lib/cache/entry.js b/deps/npm/node_modules/make-fetch-happen/lib/cache/entry.js index 45141095074ecb..bfcfacbcc95e18 100644 --- a/deps/npm/node_modules/make-fetch-happen/lib/cache/entry.js +++ b/deps/npm/node_modules/make-fetch-happen/lib/cache/entry.js @@ -274,6 +274,8 @@ class CacheEntry { const cacheWritePromise = new Promise((resolve, reject) => { cacheWriteResolve = resolve cacheWriteReject = reject + }).catch((err) => { + body.emit('error', err) }) body = new CachingMinipassPipeline({ events: ['integrity', 'size'] }, new MinipassFlush({ diff --git a/deps/npm/node_modules/make-fetch-happen/lib/remote.js b/deps/npm/node_modules/make-fetch-happen/lib/remote.js index 2aef9f8f969b00..8554564074de6e 100644 --- a/deps/npm/node_modules/make-fetch-happen/lib/remote.js +++ b/deps/npm/node_modules/make-fetch-happen/lib/remote.js @@ -2,6 +2,7 @@ const { Minipass } = require('minipass') const fetch = require('minipass-fetch') const promiseRetry = require('promise-retry') const ssri = require('ssri') +const { log } = require('proc-log') const CachingMinipassPipeline = require('./pipeline.js') const { getAgent } = require('@npmcli/agent') @@ -89,6 +90,8 @@ const remoteFetch = (request, options) => { options.onRetry(res) } + /* eslint-disable-next-line max-len */ + log.http('fetch', `${req.method} ${req.url} attempt ${attemptNum} failed with ${res.status}`) return retryHandler(res) } @@ -112,6 +115,7 @@ const remoteFetch = (request, options) => { options.onRetry(err) } + log.http('fetch', `${req.method} ${req.url} attempt ${attemptNum} failed with ${err.code}`) return retryHandler(err) } }, options.retry).catch((err) => { diff --git a/deps/npm/node_modules/make-fetch-happen/package.json b/deps/npm/node_modules/make-fetch-happen/package.json index a874ace6d1d472..7adb4d1e7f9719 100644 --- a/deps/npm/node_modules/make-fetch-happen/package.json +++ b/deps/npm/node_modules/make-fetch-happen/package.json @@ -1,6 +1,6 @@ { "name": "make-fetch-happen", - "version": "13.0.0", + "version": "13.0.1", "description": "Opinionated, caching, retrying fetch client", "main": "lib/index.js", "files": [ @@ -11,7 +11,7 @@ "test": "tap", "posttest": "npm run lint", "eslint": "eslint", - "lint": "eslint \"**/*.js\"", + "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "lintfix": "npm run lint -- --fix", "postlint": "template-oss-check", "snap": "tap", @@ -42,12 +42,13 @@ "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", + "proc-log": "^4.2.0", "promise-retry": "^2.0.1", "ssri": "^10.0.0" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.18.0", + "@npmcli/template-oss": "4.21.4", "nock": "^13.2.4", "safe-buffer": "^5.2.1", "standard-version": "^9.3.2", @@ -68,13 +69,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "ciVersions": [ - "16.14.0", - "16.x", - "18.0.0", - "18.x" - ], - "version": "4.18.0", + "version": "4.21.4", "publish": "true" } } diff --git a/deps/npm/node_modules/@npmcli/disparity-colors/LICENSE b/deps/npm/node_modules/node-gyp/node_modules/proc-log/LICENSE similarity index 96% rename from deps/npm/node_modules/@npmcli/disparity-colors/LICENSE rename to deps/npm/node_modules/node-gyp/node_modules/proc-log/LICENSE index dedcd7d2f9daec..83837797202b70 100644 --- a/deps/npm/node_modules/@npmcli/disparity-colors/LICENSE +++ b/deps/npm/node_modules/node-gyp/node_modules/proc-log/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) npm Inc. +Copyright (c) GitHub, 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 diff --git a/deps/npm/node_modules/node-gyp/node_modules/proc-log/lib/index.js b/deps/npm/node_modules/node-gyp/node_modules/proc-log/lib/index.js new file mode 100644 index 00000000000000..7c5dfad3b7ba3f --- /dev/null +++ b/deps/npm/node_modules/node-gyp/node_modules/proc-log/lib/index.js @@ -0,0 +1,23 @@ +// emits 'log' events on the process +const LEVELS = [ + 'notice', + 'error', + 'warn', + 'info', + 'verbose', + 'http', + 'silly', + 'pause', + 'resume', +] + +const log = level => (...args) => process.emit('log', level, ...args) + +const logger = {} +for (const level of LEVELS) { + logger[level] = log(level) +} + +logger.LEVELS = LEVELS + +module.exports = logger diff --git a/deps/npm/node_modules/npmlog/package.json b/deps/npm/node_modules/node-gyp/node_modules/proc-log/package.json similarity index 59% rename from deps/npm/node_modules/npmlog/package.json rename to deps/npm/node_modules/node-gyp/node_modules/proc-log/package.json index dbcc772d37ab7a..d335fa965ace51 100644 --- a/deps/npm/node_modules/npmlog/package.json +++ b/deps/npm/node_modules/node-gyp/node_modules/proc-log/package.json @@ -1,52 +1,44 @@ { - "author": "GitHub Inc.", - "name": "npmlog", - "description": "logger for npm", - "version": "7.0.1", - "repository": { - "type": "git", - "url": "https://github.com/npm/npmlog.git" - }, - "main": "lib/log.js", + "name": "proc-log", + "version": "3.0.0", "files": [ "bin/", "lib/" ], + "main": "lib/index.js", + "description": "just emit 'log' events on the process object", + "repository": { + "type": "git", + "url": "https://github.com/npm/proc-log.git" + }, + "author": "GitHub Inc.", + "license": "ISC", "scripts": { "test": "tap", - "npmclilint": "npmcli-lint", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", + "snap": "tap", "posttest": "npm run lint", - "postsnap": "npm run lintfix --", + "postsnap": "eslint index.js test/*.js --fix", + "lint": "eslint \"**/*.js\"", "postlint": "template-oss-check", - "snap": "tap", + "lintfix": "npm run lint -- --fix", "template-oss-apply": "template-oss-apply --force" }, - "dependencies": { - "are-we-there-yet": "^4.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^5.0.0", - "set-blocking": "^2.0.0" - }, "devDependencies": { - "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.6.1", + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/template-oss": "4.5.1", "tap": "^16.0.1" }, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.5.1" + }, "tap": { - "branches": 95, "nyc-arg": [ "--exclude", "tap-snapshots/**" ] - }, - "templateOSS": { - "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.6.1" } } diff --git a/deps/npm/node_modules/npm-package-arg/lib/npa.js b/deps/npm/node_modules/npm-package-arg/lib/npa.js index 23bf68d2e04a39..6a3f07da929d87 100644 --- a/deps/npm/node_modules/npm-package-arg/lib/npa.js +++ b/deps/npm/node_modules/npm-package-arg/lib/npa.js @@ -10,7 +10,7 @@ const semver = require('semver') const path = global.FAKE_WINDOWS ? require('path').win32 : require('path') const validatePackageName = require('validate-npm-package-name') const { homedir } = require('os') -const log = require('proc-log') +const { log } = require('proc-log') const isWindows = process.platform === 'win32' || global.FAKE_WINDOWS const hasSlashes = isWindows ? /\\|[/]/ : /[/]/ diff --git a/deps/npm/node_modules/npm-package-arg/package.json b/deps/npm/node_modules/npm-package-arg/package.json index f7965d5a007c9d..c4cee1f928e89d 100644 --- a/deps/npm/node_modules/npm-package-arg/package.json +++ b/deps/npm/node_modules/npm-package-arg/package.json @@ -1,6 +1,6 @@ { "name": "npm-package-arg", - "version": "11.0.1", + "version": "11.0.2", "description": "Parse the things that can be arguments to `npm install`", "main": "./lib/npa.js", "directories": { @@ -12,20 +12,20 @@ ], "dependencies": { "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^5.0.0" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.18.0", + "@npmcli/template-oss": "4.21.3", "tap": "^16.0.1" }, "scripts": { "test": "tap", "snap": "tap", "npmclilint": "npmcli-lint", - "lint": "eslint \"**/*.js\"", + "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "lintfix": "npm run lint -- --fix", "posttest": "npm run lint", "postsnap": "npm run lintfix --", @@ -54,14 +54,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.18.0", - "publish": true, - "ciVersions": [ - "16.14.0", - "16.x", - "18.0.0", - "18.x" - ], - "npmSpec": "next-9" + "version": "4.21.3", + "publish": true } } diff --git a/deps/npm/node_modules/npm-profile/lib/index.js b/deps/npm/node_modules/npm-profile/lib/index.js index ce78882a55438d..e5b5dd046baf2e 100644 --- a/deps/npm/node_modules/npm-profile/lib/index.js +++ b/deps/npm/node_modules/npm-profile/lib/index.js @@ -5,7 +5,7 @@ const { HttpErrorBase } = require('npm-registry-fetch/lib/errors') const EventEmitter = require('events') const os = require('os') const { URL } = require('url') -const log = require('proc-log') +const { log } = require('proc-log') // try loginWeb, catch the "not supported" message and fall back to couch const login = (opener, prompter, opts = {}) => { @@ -276,8 +276,7 @@ class WebLoginNotSupported extends HttpErrorBase { } } -const sleep = (ms) => - new Promise((resolve, reject) => setTimeout(resolve, ms)) +const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)) module.exports = { adduserCouch, diff --git a/deps/npm/node_modules/npm-profile/package.json b/deps/npm/node_modules/npm-profile/package.json index af57e9e73509c3..acdf4d6baf2ee3 100644 --- a/deps/npm/node_modules/npm-profile/package.json +++ b/deps/npm/node_modules/npm-profile/package.json @@ -1,13 +1,13 @@ { "name": "npm-profile", - "version": "9.0.0", + "version": "9.0.2", "description": "Library for updating an npmjs.com profile", "keywords": [], "author": "GitHub Inc.", "license": "ISC", "dependencies": { - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0" + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0" }, "main": "./lib/index.js", "repository": { @@ -20,7 +20,7 @@ ], "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.18.0", + "@npmcli/template-oss": "4.21.4", "nock": "^13.2.4", "tap": "^16.0.1" }, @@ -28,7 +28,7 @@ "posttest": "npm run lint", "test": "tap", "snap": "tap", - "lint": "eslint \"**/*.js\"", + "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "postlint": "template-oss-check", "lintfix": "npm run lint -- --fix", "template-oss-apply": "template-oss-apply --force" @@ -45,13 +45,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.18.0", - "ciVersions": [ - "16.14.0", - "16.x", - "18.0.0", - "18.x" - ], + "version": "4.21.4", "publish": true } } diff --git a/deps/npm/node_modules/npm-registry-fetch/lib/check-response.js b/deps/npm/node_modules/npm-registry-fetch/lib/check-response.js index 183311d8403977..65eea2963b0b4c 100644 --- a/deps/npm/node_modules/npm-registry-fetch/lib/check-response.js +++ b/deps/npm/node_modules/npm-registry-fetch/lib/check-response.js @@ -3,7 +3,7 @@ const errors = require('./errors.js') const { Response } = require('minipass-fetch') const defaultOpts = require('./default-opts.js') -const log = require('proc-log') +const { log } = require('proc-log') const { redact: cleanUrl } = require('@npmcli/redact') /* eslint-disable-next-line max-len */ diff --git a/deps/npm/node_modules/npm-registry-fetch/lib/index.js b/deps/npm/node_modules/npm-registry-fetch/lib/index.js index 1d77a77024bf50..bce6e6b1aae0ac 100644 --- a/deps/npm/node_modules/npm-registry-fetch/lib/index.js +++ b/deps/npm/node_modules/npm-registry-fetch/lib/index.js @@ -10,7 +10,6 @@ const qs = require('querystring') const url = require('url') const zlib = require('minizlib') const { Minipass } = require('minipass') -const { redact: cleanUrl } = require('@npmcli/redact') const defaultOpts = require('./default-opts.js') @@ -246,7 +245,3 @@ function getHeaders (uri, auth, opts) { return headers } - -// export cleanUrl to avoid a breaking change -// TODO: next semver major remove this. Consumers should use @npmcli/redact instead -module.exports.cleanUrl = cleanUrl diff --git a/deps/npm/node_modules/npm-registry-fetch/package.json b/deps/npm/node_modules/npm-registry-fetch/package.json index 88455a4971af0b..52820a6a206ecb 100644 --- a/deps/npm/node_modules/npm-registry-fetch/package.json +++ b/deps/npm/node_modules/npm-registry-fetch/package.json @@ -1,6 +1,6 @@ { "name": "npm-registry-fetch", - "version": "16.2.0", + "version": "17.0.0", "description": "Fetch-based http client for use with npm registry APIs", "main": "lib", "files": [ @@ -31,18 +31,18 @@ "author": "GitHub Inc.", "license": "ISC", "dependencies": { - "@npmcli/redact": "^1.1.0", + "@npmcli/redact": "^2.0.0", "make-fetch-happen": "^13.0.0", "minipass": "^7.0.2", "minipass-fetch": "^3.0.0", "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", "npm-package-arg": "^11.0.0", - "proc-log": "^3.0.0" + "proc-log": "^4.0.0" }, "devDependencies": { "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.21.3", + "@npmcli/template-oss": "4.21.4", "cacache": "^18.0.0", "nock": "^13.2.4", "require-inject": "^1.4.4", @@ -62,7 +62,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.21.3", + "version": "4.21.4", "publish": "true" } } diff --git a/deps/npm/node_modules/npmlog/LICENSE.md b/deps/npm/node_modules/npmlog/LICENSE.md deleted file mode 100644 index 5fc208ff122e08..00000000000000 --- a/deps/npm/node_modules/npmlog/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ - - -ISC License - -Copyright npm, Inc. - -Permission to use, copy, modify, and/or distribute this -software for any purpose with or without fee is hereby -granted, provided that the above copyright notice and this -permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO -EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE -USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/deps/npm/node_modules/npmlog/lib/log.js b/deps/npm/node_modules/npmlog/lib/log.js deleted file mode 100644 index 38106ea34ae08d..00000000000000 --- a/deps/npm/node_modules/npmlog/lib/log.js +++ /dev/null @@ -1,400 +0,0 @@ -'use strict' -var Progress = require('are-we-there-yet') -var Gauge = require('gauge') -var EE = require('events').EventEmitter -var log = exports = module.exports = new EE() -var util = require('util') - -var setBlocking = require('set-blocking') -var consoleControl = require('console-control-strings') - -setBlocking(true) -var stream = process.stderr -Object.defineProperty(log, 'stream', { - set: function (newStream) { - stream = newStream - if (this.gauge) { - this.gauge.setWriteTo(stream, stream) - } - }, - get: function () { - return stream - }, -}) - -// by default, decide based on tty-ness. -var colorEnabled -log.useColor = function () { - return colorEnabled != null ? colorEnabled : stream.isTTY -} - -log.enableColor = function () { - colorEnabled = true - this.gauge.setTheme({ hasColor: colorEnabled, hasUnicode: unicodeEnabled }) -} -log.disableColor = function () { - colorEnabled = false - this.gauge.setTheme({ hasColor: colorEnabled, hasUnicode: unicodeEnabled }) -} - -// default level -log.level = 'info' - -log.gauge = new Gauge(stream, { - enabled: false, // no progress bars unless asked - theme: { hasColor: log.useColor() }, - template: [ - { type: 'progressbar', length: 20 }, - { type: 'activityIndicator', kerning: 1, length: 1 }, - { type: 'section', default: '' }, - ':', - { type: 'logline', kerning: 1, default: '' }, - ], -}) - -log.tracker = new Progress.TrackerGroup() - -// we track this separately as we may need to temporarily disable the -// display of the status bar for our own loggy purposes. -log.progressEnabled = log.gauge.isEnabled() - -var unicodeEnabled - -log.enableUnicode = function () { - unicodeEnabled = true - this.gauge.setTheme({ hasColor: this.useColor(), hasUnicode: unicodeEnabled }) -} - -log.disableUnicode = function () { - unicodeEnabled = false - this.gauge.setTheme({ hasColor: this.useColor(), hasUnicode: unicodeEnabled }) -} - -log.setGaugeThemeset = function (themes) { - this.gauge.setThemeset(themes) -} - -log.setGaugeTemplate = function (template) { - this.gauge.setTemplate(template) -} - -log.enableProgress = function () { - if (this.progressEnabled || this._paused) { - return - } - - this.progressEnabled = true - this.tracker.on('change', this.showProgress) - this.gauge.enable() -} - -log.disableProgress = function () { - if (!this.progressEnabled) { - return - } - this.progressEnabled = false - this.tracker.removeListener('change', this.showProgress) - this.gauge.disable() -} - -var trackerConstructors = ['newGroup', 'newItem', 'newStream'] - -var mixinLog = function (tracker) { - // mixin the public methods from log into the tracker - // (except: conflicts and one's we handle specially) - Object.keys(log).forEach(function (P) { - if (P[0] === '_') { - return - } - - if (trackerConstructors.filter(function (C) { - return C === P - }).length) { - return - } - - if (tracker[P]) { - return - } - - if (typeof log[P] !== 'function') { - return - } - - var func = log[P] - tracker[P] = function () { - return func.apply(log, arguments) - } - }) - // if the new tracker is a group, make sure any subtrackers get - // mixed in too - if (tracker instanceof Progress.TrackerGroup) { - trackerConstructors.forEach(function (C) { - var func = tracker[C] - tracker[C] = function () { - return mixinLog(func.apply(tracker, arguments)) - } - }) - } - return tracker -} - -// Add tracker constructors to the top level log object -trackerConstructors.forEach(function (C) { - log[C] = function () { - return mixinLog(this.tracker[C].apply(this.tracker, arguments)) - } -}) - -log.clearProgress = function (cb) { - if (!this.progressEnabled) { - return cb && process.nextTick(cb) - } - - this.gauge.hide(cb) -} - -log.showProgress = function (name, completed) { - if (!this.progressEnabled) { - return - } - - var values = {} - if (name) { - values.section = name - } - - var last = log.record[log.record.length - 1] - if (last) { - values.subsection = last.prefix - var disp = log.disp[last.level] || last.level - var logline = this._format(disp, log.style[last.level]) - if (last.prefix) { - logline += ' ' + this._format(last.prefix, this.prefixStyle) - } - - logline += ' ' + last.message.split(/\r?\n/)[0] - values.logline = logline - } - values.completed = completed || this.tracker.completed() - this.gauge.show(values) -}.bind(log) // bind for use in tracker's on-change listener - -// temporarily stop emitting, but don't drop -log.pause = function () { - this._paused = true - if (this.progressEnabled) { - this.gauge.disable() - } -} - -log.resume = function () { - if (!this._paused) { - return - } - - this._paused = false - - var b = this._buffer - this._buffer = [] - b.forEach(function (m) { - this.emitLog(m) - }, this) - if (this.progressEnabled) { - this.gauge.enable() - } -} - -log._buffer = [] - -var id = 0 -log.record = [] -log.maxRecordSize = 10000 -log.log = function (lvl, prefix, message) { - var l = this.levels[lvl] - if (l === undefined) { - return this.emit('error', new Error(util.format( - 'Undefined log level: %j', lvl))) - } - - var a = new Array(arguments.length - 2) - var stack = null - for (var i = 2; i < arguments.length; i++) { - var arg = a[i - 2] = arguments[i] - - // resolve stack traces to a plain string. - if (typeof arg === 'object' && arg instanceof Error && arg.stack) { - Object.defineProperty(arg, 'stack', { - value: stack = arg.stack + '', - enumerable: true, - writable: true, - }) - } - } - if (stack) { - a.unshift(stack + '\n') - } - message = util.format.apply(util, a) - - var m = { - id: id++, - level: lvl, - prefix: String(prefix || ''), - message: message, - messageRaw: a, - } - - this.emit('log', m) - this.emit('log.' + lvl, m) - if (m.prefix) { - this.emit(m.prefix, m) - } - - this.record.push(m) - var mrs = this.maxRecordSize - var n = this.record.length - mrs - if (n > mrs / 10) { - var newSize = Math.floor(mrs * 0.9) - this.record = this.record.slice(-1 * newSize) - } - - this.emitLog(m) -}.bind(log) - -log.emitLog = function (m) { - if (this._paused) { - this._buffer.push(m) - return - } - if (this.progressEnabled) { - this.gauge.pulse(m.prefix) - } - - var l = this.levels[m.level] - if (l === undefined) { - return - } - - if (l < this.levels[this.level]) { - return - } - - if (l > 0 && !isFinite(l)) { - return - } - - // If 'disp' is null or undefined, use the lvl as a default - // Allows: '', 0 as valid disp - var disp = log.disp[m.level] != null ? log.disp[m.level] : m.level - this.clearProgress() - m.message.split(/\r?\n/).forEach(function (line) { - var heading = this.heading - if (heading) { - this.write(heading, this.headingStyle) - this.write(' ') - } - this.write(disp, log.style[m.level]) - var p = m.prefix || '' - if (p) { - this.write(' ') - } - - this.write(p, this.prefixStyle) - this.write(' ' + line + '\n') - }, this) - this.showProgress() -} - -log._format = function (msg, style) { - if (!stream) { - return - } - - var output = '' - if (this.useColor()) { - style = style || {} - var settings = [] - if (style.fg) { - settings.push(style.fg) - } - - if (style.bg) { - settings.push('bg' + style.bg[0].toUpperCase() + style.bg.slice(1)) - } - - if (style.bold) { - settings.push('bold') - } - - if (style.underline) { - settings.push('underline') - } - - if (style.inverse) { - settings.push('inverse') - } - - if (settings.length) { - output += consoleControl.color(settings) - } - - if (style.beep) { - output += consoleControl.beep() - } - } - output += msg - if (this.useColor()) { - output += consoleControl.color('reset') - } - - return output -} - -log.write = function (msg, style) { - if (!stream) { - return - } - - stream.write(this._format(msg, style)) -} - -log.addLevel = function (lvl, n, style, disp) { - // If 'disp' is null or undefined, use the lvl as a default - if (disp == null) { - disp = lvl - } - - this.levels[lvl] = n - this.style[lvl] = style - if (!this[lvl]) { - this[lvl] = function () { - var a = new Array(arguments.length + 1) - a[0] = lvl - for (var i = 0; i < arguments.length; i++) { - a[i + 1] = arguments[i] - } - - return this.log.apply(this, a) - }.bind(this) - } - this.disp[lvl] = disp -} - -log.prefixStyle = { fg: 'magenta' } -log.headingStyle = { fg: 'white', bg: 'black' } - -log.style = {} -log.levels = {} -log.disp = {} -log.addLevel('silly', -Infinity, { inverse: true }, 'sill') -log.addLevel('verbose', 1000, { fg: 'cyan', bg: 'black' }, 'verb') -log.addLevel('info', 2000, { fg: 'green' }) -log.addLevel('timing', 2500, { fg: 'green', bg: 'black' }) -log.addLevel('http', 3000, { fg: 'green', bg: 'black' }) -log.addLevel('notice', 3500, { fg: 'cyan', bg: 'black' }) -log.addLevel('warn', 4000, { fg: 'black', bg: 'yellow' }, 'WARN') -log.addLevel('error', 5000, { fg: 'red', bg: 'black' }, 'ERR!') -log.addLevel('silent', Infinity) - -// allow 'error' prefix -log.on('error', function () {}) diff --git a/deps/npm/node_modules/pacote/README.md b/deps/npm/node_modules/pacote/README.md index 17c027dfa048f3..dbb0051de23a4d 100644 --- a/deps/npm/node_modules/pacote/README.md +++ b/deps/npm/node_modules/pacote/README.md @@ -166,8 +166,6 @@ resolved, and other properties, as they are determined. calls. This allows you to easily avoid hitting the registry multiple times (even just to validate the cache) for a given packument, since it is unlikely to change in the span of a single command. -* `silent` A boolean that determines whether the banner is displayed - when calling `@npmcli/run-script`. * `verifySignatures` A boolean that will make pacote verify the integrity signature of a manifest, if present. There must be a configured `_keys` entry in the config that is scoped to the diff --git a/deps/npm/node_modules/pacote/lib/dir.js b/deps/npm/node_modules/pacote/lib/dir.js index 420afc5802cb2f..135be8e6cba833 100644 --- a/deps/npm/node_modules/pacote/lib/dir.js +++ b/deps/npm/node_modules/pacote/lib/dir.js @@ -41,16 +41,11 @@ class DirFetcher extends Fetcher { // but this function is *also* run when installing git deps const stdio = this.opts.foregroundScripts ? 'inherit' : 'pipe' - // hide the banner if silent opt is passed in, or if prepare running - // in the background. - const banner = this.opts.silent ? false : stdio === 'inherit' - return runScript({ pkg: mani, event: 'prepare', path: this.resolved, stdio, - banner, env: { npm_package_resolved: this.resolved, npm_package_integrity: this.integrity, @@ -92,7 +87,7 @@ class DirFetcher extends Fetcher { return Promise.resolve(this.package) } - return this[_readPackageJson](this.resolved + '/package.json') + return this[_readPackageJson](this.resolved) .then(mani => this.package = { ...mani, _integrity: this.integrity && String(this.integrity), diff --git a/deps/npm/node_modules/pacote/lib/fetcher.js b/deps/npm/node_modules/pacote/lib/fetcher.js index f961a45c7d3461..c4a707e7ef81ef 100644 --- a/deps/npm/node_modules/pacote/lib/fetcher.js +++ b/deps/npm/node_modules/pacote/lib/fetcher.js @@ -5,10 +5,9 @@ const npa = require('npm-package-arg') const ssri = require('ssri') -const { promisify } = require('util') const { basename, dirname } = require('path') const tar = require('tar') -const log = require('proc-log') +const { log } = require('proc-log') const retry = require('promise-retry') const fs = require('fs/promises') const fsm = require('fs-minipass') @@ -16,12 +15,14 @@ const cacache = require('cacache') const isPackageBin = require('./util/is-package-bin.js') const removeTrailingSlashes = require('./util/trailing-slashes.js') const getContents = require('@npmcli/installed-package-contents') -const readPackageJsonFast = require('read-package-json-fast') -const readPackageJson = promisify(require('read-package-json')) +const PackageJson = require('@npmcli/package-json') const { Minipass } = require('minipass') - const cacheDir = require('./util/cache-dir.js') +// Pacote is only concerned with the package.json contents +const packageJsonPrepare = (p) => PackageJson.prepare(p).then(pkg => pkg.content) +const packageJsonNormalize = (p) => PackageJson.normalize(p).then(pkg => pkg.content) + // Private methods. // Child classes should not have to override these. // Users should never call them. @@ -93,9 +94,9 @@ class FetcherBase { this.fullMetadata = this.before ? true : !!opts.fullMetadata this.fullReadJson = !!opts.fullReadJson if (this.fullReadJson) { - this[_readPackageJson] = readPackageJson + this[_readPackageJson] = packageJsonPrepare } else { - this[_readPackageJson] = readPackageJsonFast + this[_readPackageJson] = packageJsonNormalize } // rrh is a registry hostname or 'never' or 'always' diff --git a/deps/npm/node_modules/pacote/lib/file.js b/deps/npm/node_modules/pacote/lib/file.js index bf99bb86e359ed..95769de1374c97 100644 --- a/deps/npm/node_modules/pacote/lib/file.js +++ b/deps/npm/node_modules/pacote/lib/file.js @@ -1,10 +1,11 @@ -const Fetcher = require('./fetcher.js') const fsm = require('fs-minipass') const cacache = require('cacache') -const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') -const _exeBins = Symbol('_exeBins') const { resolve } = require('path') -const fs = require('fs') +const { stat, chmod } = require('fs/promises') +const Fetcher = require('./fetcher.js') + +const _exeBins = Symbol('_exeBins') +const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson') class FileFetcher extends Fetcher { @@ -26,7 +27,7 @@ class FileFetcher extends Fetcher { // have to unpack the tarball for this. return cacache.tmp.withTmp(this.cache, this.opts, dir => this.extract(dir) - .then(() => this[_readPackageJson](dir + '/package.json')) + .then(() => this[_readPackageJson](dir)) .then(mani => this.package = { ...mani, _integrity: this.integrity && String(this.integrity), @@ -40,23 +41,23 @@ class FileFetcher extends Fetcher { return Promise.resolve() } - return Promise.all(Object.keys(pkg.bin).map(k => new Promise(res => { + return Promise.all(Object.keys(pkg.bin).map(async k => { const script = resolve(dest, pkg.bin[k]) // Best effort. Ignore errors here, the only result is that // a bin script is not executable. But if it's missing or // something, we just leave it for a later stage to trip over // when we can provide a more useful contextual error. - fs.stat(script, (er, st) => { - if (er) { - return res() - } + try { + const st = await stat(script) const mode = st.mode | 0o111 if (mode === st.mode) { - return res() + return } - fs.chmod(script, mode, res) - }) - }))) + await chmod(script, mode) + } catch { + // Ignore errors here + } + })) } extract (dest) { @@ -64,7 +65,7 @@ class FileFetcher extends Fetcher { // but if not, read the unpacked manifest and chmod properly. return super.extract(dest) .then(result => this.package ? result - : this[_readPackageJson](dest + '/package.json').then(pkg => + : this[_readPackageJson](dest).then(pkg => this[_exeBins](pkg, dest)).then(() => result)) } diff --git a/deps/npm/node_modules/pacote/lib/git.js b/deps/npm/node_modules/pacote/lib/git.js index 5d24f72497ec9e..2cac44ae528e6e 100644 --- a/deps/npm/node_modules/pacote/lib/git.js +++ b/deps/npm/node_modules/pacote/lib/git.js @@ -8,7 +8,7 @@ const pickManifest = require('npm-pick-manifest') const npa = require('npm-package-arg') const { Minipass } = require('minipass') const cacache = require('cacache') -const log = require('proc-log') +const { log } = require('proc-log') const npm = require('./util/npm.js') const _resolvedFromRepo = Symbol('_resolvedFromRepo') @@ -156,11 +156,11 @@ class GitFetcher extends Fetcher { [_resolvedFromClone] () { // do a full or shallow clone, then look at the HEAD // kind of wasteful, but no other option, really - return this[_clone](dir => this.resolved) + return this[_clone](() => this.resolved) } [_prepareDir] (dir) { - return this[_readPackageJson](dir + '/package.json').then(mani => { + return this[_readPackageJson](dir).then(mani => { // no need if we aren't going to do any preparation. const scripts = mani.scripts if (!mani.workspaces && (!scripts || !( @@ -312,7 +312,7 @@ class GitFetcher extends Fetcher { return this.spec.hosted && this.resolved ? FileFetcher.prototype.manifest.apply(this) : this[_clone](dir => - this[_readPackageJson](dir + '/package.json') + this[_readPackageJson](dir) .then(mani => this.package = { ...mani, _resolved: this.resolved, diff --git a/deps/npm/node_modules/pacote/lib/registry.js b/deps/npm/node_modules/pacote/lib/registry.js index de25a11af46672..b6a8d49b84f321 100644 --- a/deps/npm/node_modules/pacote/lib/registry.js +++ b/deps/npm/node_modules/pacote/lib/registry.js @@ -3,7 +3,7 @@ const RemoteFetcher = require('./remote.js') const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') const pacoteVersion = require('../package.json').version const removeTrailingSlashes = require('./util/trailing-slashes.js') -const rpj = require('read-package-json-fast') +const PackageJson = require('@npmcli/package-json') const pickManifest = require('npm-pick-manifest') const ssri = require('ssri') const crypto = require('crypto') @@ -127,12 +127,13 @@ class RegistryFetcher extends Fetcher { } const packument = await this.packument() - let mani = await pickManifest(packument, this.spec.fetchSpec, { + const steps = PackageJson.normalizeSteps.filter(s => s !== '_attributes') + const mani = await new PackageJson().fromContent(pickManifest(packument, this.spec.fetchSpec, { ...this.opts, defaultTag: this.defaultTag, before: this.before, - }) - mani = rpj.normalize(mani) + })).normalize({ steps }).then(p => p.content) + /* XXX add ETARGET and E403 revalidation of cached packuments here */ // add _time from packument if fetched with fullMetadata diff --git a/deps/npm/node_modules/pacote/package.json b/deps/npm/node_modules/pacote/package.json index 8fc0bb707f1e52..4c1751644cd57a 100644 --- a/deps/npm/node_modules/pacote/package.json +++ b/deps/npm/node_modules/pacote/package.json @@ -1,6 +1,6 @@ { "name": "pacote", - "version": "17.0.6", + "version": "18.0.3", "description": "JavaScript package downloader", "author": "GitHub Inc.", "bin": { @@ -27,7 +27,7 @@ "devDependencies": { "@npmcli/arborist": "^7.1.0", "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.21.3", + "@npmcli/template-oss": "4.21.4", "hosted-git-info": "^7.0.0", "mutate-fs": "^2.1.1", "nock": "^13.2.4", @@ -46,19 +46,18 @@ "dependencies": { "@npmcli/git": "^5.0.0", "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/package-json": "^5.1.0", "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", + "@npmcli/run-script": "^8.0.0", "cacache": "^18.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^11.0.0", "npm-packlist": "^8.0.0", "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0", "promise-retry": "^2.0.1", - "read-package-json": "^7.0.0", - "read-package-json-fast": "^3.0.0", "sigstore": "^2.2.0", "ssri": "^10.0.0", "tar": "^6.1.11" @@ -72,7 +71,7 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.21.3", + "version": "4.21.4", "windowsCI": false, "publish": "true" } diff --git a/deps/npm/node_modules/proc-log/lib/index.js b/deps/npm/node_modules/proc-log/lib/index.js index 7c5dfad3b7ba3f..86d90861078dab 100644 --- a/deps/npm/node_modules/proc-log/lib/index.js +++ b/deps/npm/node_modules/proc-log/lib/index.js @@ -1,23 +1,153 @@ -// emits 'log' events on the process -const LEVELS = [ - 'notice', - 'error', - 'warn', - 'info', - 'verbose', - 'http', - 'silly', - 'pause', - 'resume', -] - -const log = level => (...args) => process.emit('log', level, ...args) - -const logger = {} -for (const level of LEVELS) { - logger[level] = log(level) +const META = Symbol('proc-log.meta') +module.exports = { + META: META, + output: { + LEVELS: [ + 'standard', + 'error', + 'buffer', + 'flush', + ], + KEYS: { + standard: 'standard', + error: 'error', + buffer: 'buffer', + flush: 'flush', + }, + standard: function (...args) { + return process.emit('output', 'standard', ...args) + }, + error: function (...args) { + return process.emit('output', 'error', ...args) + }, + buffer: function (...args) { + return process.emit('output', 'buffer', ...args) + }, + flush: function (...args) { + return process.emit('output', 'flush', ...args) + }, + }, + log: { + LEVELS: [ + 'notice', + 'error', + 'warn', + 'info', + 'verbose', + 'http', + 'silly', + 'timing', + 'pause', + 'resume', + ], + KEYS: { + notice: 'notice', + error: 'error', + warn: 'warn', + info: 'info', + verbose: 'verbose', + http: 'http', + silly: 'silly', + timing: 'timing', + pause: 'pause', + resume: 'resume', + }, + error: function (...args) { + return process.emit('log', 'error', ...args) + }, + notice: function (...args) { + return process.emit('log', 'notice', ...args) + }, + warn: function (...args) { + return process.emit('log', 'warn', ...args) + }, + info: function (...args) { + return process.emit('log', 'info', ...args) + }, + verbose: function (...args) { + return process.emit('log', 'verbose', ...args) + }, + http: function (...args) { + return process.emit('log', 'http', ...args) + }, + silly: function (...args) { + return process.emit('log', 'silly', ...args) + }, + timing: function (...args) { + return process.emit('log', 'timing', ...args) + }, + pause: function () { + return process.emit('log', 'pause') + }, + resume: function () { + return process.emit('log', 'resume') + }, + }, + time: { + LEVELS: [ + 'start', + 'end', + ], + KEYS: { + start: 'start', + end: 'end', + }, + start: function (name, fn) { + process.emit('time', 'start', name) + function end () { + return process.emit('time', 'end', name) + } + if (typeof fn === 'function') { + const res = fn() + if (res && res.finally) { + return res.finally(end) + } + end() + return res + } + return end + }, + end: function (name) { + return process.emit('time', 'end', name) + }, + }, + input: { + LEVELS: [ + 'start', + 'end', + 'read', + ], + KEYS: { + start: 'start', + end: 'end', + read: 'read', + }, + start: function (fn) { + process.emit('input', 'start') + function end () { + return process.emit('input', 'end') + } + if (typeof fn === 'function') { + const res = fn() + if (res && res.finally) { + return res.finally(end) + } + end() + return res + } + return end + }, + end: function () { + return process.emit('input', 'end') + }, + read: function (...args) { + let resolve, reject + const promise = new Promise((_resolve, _reject) => { + resolve = _resolve + reject = _reject + }) + process.emit('input', 'read', resolve, reject, ...args) + return promise + }, + }, } - -logger.LEVELS = LEVELS - -module.exports = logger diff --git a/deps/npm/node_modules/proc-log/package.json b/deps/npm/node_modules/proc-log/package.json index d335fa965ace51..4ab89102ecc9b5 100644 --- a/deps/npm/node_modules/proc-log/package.json +++ b/deps/npm/node_modules/proc-log/package.json @@ -1,6 +1,6 @@ { "name": "proc-log", - "version": "3.0.0", + "version": "4.2.0", "files": [ "bin/", "lib/" @@ -18,14 +18,14 @@ "snap": "tap", "posttest": "npm run lint", "postsnap": "eslint index.js test/*.js --fix", - "lint": "eslint \"**/*.js\"", + "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "postlint": "template-oss-check", "lintfix": "npm run lint -- --fix", "template-oss-apply": "template-oss-apply --force" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "4.5.1", + "@npmcli/eslint-config": "^4.0.0", + "@npmcli/template-oss": "4.21.3", "tap": "^16.0.1" }, "engines": { @@ -33,7 +33,8 @@ }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.5.1" + "version": "4.21.3", + "publish": true }, "tap": { "nyc-arg": [ diff --git a/deps/npm/node_modules/color-support/LICENSE b/deps/npm/node_modules/proggy/LICENSE similarity index 93% rename from deps/npm/node_modules/color-support/LICENSE rename to deps/npm/node_modules/proggy/LICENSE index 19129e315fe593..83837797202b70 100644 --- a/deps/npm/node_modules/color-support/LICENSE +++ b/deps/npm/node_modules/proggy/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) Isaac Z. Schlueter and Contributors +Copyright (c) GitHub, 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 diff --git a/deps/npm/node_modules/proggy/lib/client.js b/deps/npm/node_modules/proggy/lib/client.js new file mode 100644 index 00000000000000..2eafb9c75addc2 --- /dev/null +++ b/deps/npm/node_modules/proggy/lib/client.js @@ -0,0 +1,114 @@ +const EE = require('events') +const onProgress = Symbol('onProgress') +const bars = Symbol('bars') +const listener = Symbol('listener') +const normData = Symbol('normData') +class Client extends EE { + constructor ({ normalize = false, stopOnDone = false } = {}) { + super() + this.normalize = !!normalize + this.stopOnDone = !!stopOnDone + this[bars] = new Map() + this[listener] = null + } + + get size () { + return this[bars].size + } + + get listening () { + return !!this[listener] + } + + addListener (...args) { + return this.on(...args) + } + + on (ev, ...args) { + if (ev === 'progress' && !this[listener]) { + this.start() + } + return super.on(ev, ...args) + } + + off (ev, ...args) { + return this.removeListener(ev, ...args) + } + + removeListener (ev, ...args) { + const ret = super.removeListener(ev, ...args) + if (ev === 'progress' && this.listeners(ev).length === 0) { + this.stop() + } + return ret + } + + stop () { + if (this[listener]) { + process.removeListener('progress', this[listener]) + this[listener] = null + } + } + + start () { + if (!this[listener]) { + this[listener] = (...args) => this[onProgress](...args) + process.on('progress', this[listener]) + } + } + + [onProgress] (key, data) { + data = this[normData](key, data) + if (!this[bars].has(key)) { + this.emit('bar', key, data) + } + this[bars].set(key, data) + this.emit('progress', key, data) + if (data.done) { + this[bars].delete(key) + this.emit('barDone', key, data) + if (this.size === 0) { + if (this.stopOnDone) { + this.stop() + } + this.emit('done') + } + } + } + + [normData] (key, data) { + const actualValue = data.value + const actualTotal = data.total + let value = actualValue + let total = actualTotal + const done = data.done || value >= total + if (this.normalize) { + const bar = this[bars].get(key) + total = 100 + if (done) { + value = 100 + } else { + // show value as a portion of 100 + const pct = 100 * actualValue / actualTotal + if (bar) { + // don't ever go backwards, and don't stand still + // move at least 1% of the remaining value if it wouldn't move. + value = (pct > bar.value) ? pct + : (100 - bar.value) / 100 + bar.value + } + } + } + // include the key + return { + ...data, + key, + name: data.name || key, + value, + total, + actualValue, + actualTotal, + done, + } + } +} +module.exports = Client diff --git a/deps/npm/node_modules/proggy/lib/index.js b/deps/npm/node_modules/proggy/lib/index.js new file mode 100644 index 00000000000000..834948b4ff8603 --- /dev/null +++ b/deps/npm/node_modules/proggy/lib/index.js @@ -0,0 +1,15 @@ +exports.Client = require('./client.js') +exports.Tracker = require('./tracker.js') + +const trackers = new Map() +exports.createTracker = (name, key, total) => { + const tracker = new exports.Tracker(name, key, total) + if (trackers.has(tracker.key)) { + const msg = `proggy: duplicate progress id ${JSON.stringify(tracker.key)}` + throw new Error(msg) + } + trackers.set(tracker.key, tracker) + tracker.on('done', () => trackers.delete(tracker.key)) + return tracker +} +exports.createClient = (options = {}) => new exports.Client(options) diff --git a/deps/npm/node_modules/proggy/lib/tracker.js b/deps/npm/node_modules/proggy/lib/tracker.js new file mode 100644 index 00000000000000..56c78d9434dc7c --- /dev/null +++ b/deps/npm/node_modules/proggy/lib/tracker.js @@ -0,0 +1,68 @@ +// The tracker class is intentionally as naive as possible. it is just +// an ergonomic wrapper around process.emit('progress', ...) +const EE = require('events') +class Tracker extends EE { + constructor (name, key, total) { + super() + if (!name) { + throw new Error('proggy: Tracker needs a name') + } + + if (typeof key === 'number' && !total) { + total = key + key = null + } + + if (!total) { + total = 100 + } + + if (!key) { + key = name + } + + this.done = false + this.name = name + this.key = key + this.value = 0 + this.total = total + } + + finish (metadata = {}) { + this.update(this.total, this.total, metadata) + } + + update (value, total, metadata) { + if (!metadata) { + if (total && typeof total === 'object') { + metadata = total + } else { + metadata = {} + } + } + if (typeof total !== 'number') { + total = this.total + } + + if (this.done) { + const msg = `proggy: updating completed tracker: ${JSON.stringify(this.key)}` + throw new Error(msg) + } + this.value = value + this.total = total + const done = this.value >= this.total + process.emit('progress', this.key, { + ...metadata, + name: this.name, + key: this.key, + value, + total, + done, + }) + if (done) { + this.done = true + this.emit('done') + } + } +} +module.exports = Tracker diff --git a/deps/npm/node_modules/are-we-there-yet/package.json b/deps/npm/node_modules/proggy/package.json similarity index 53% rename from deps/npm/node_modules/are-we-there-yet/package.json rename to deps/npm/node_modules/proggy/package.json index f072a21abb444b..4940fc9d002a64 100644 --- a/deps/npm/node_modules/are-we-there-yet/package.json +++ b/deps/npm/node_modules/proggy/package.json @@ -1,53 +1,48 @@ { - "name": "are-we-there-yet", - "version": "4.0.2", - "description": "Keep track of the overall completion of many disparate processes", + "name": "proggy", + "version": "2.0.0", + "files": [ + "bin/", + "lib/" + ], "main": "lib/index.js", + "description": "Progress bar updates at a distance", + "repository": { + "type": "git", + "url": "https://github.com/npm/proggy.git" + }, + "author": "GitHub Inc.", + "license": "ISC", "scripts": { "test": "tap", - "lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", - "lintfix": "npm run lint -- --fix", "posttest": "npm run lint", - "postsnap": "npm run lintfix --", "snap": "tap", + "postsnap": "eslint lib test --fix", + "lint": "eslint \"**/*.js\"", "postlint": "template-oss-check", + "lintfix": "npm run lint -- --fix", "template-oss-apply": "template-oss-apply --force" }, - "repository": { - "type": "git", - "url": "https://github.com/npm/are-we-there-yet.git" - }, - "author": "GitHub Inc.", - "license": "ISC", - "bugs": { - "url": "https://github.com/npm/are-we-there-yet/issues" - }, - "homepage": "https://github.com/npm/are-we-there-yet", "devDependencies": { - "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.21.3", + "@npmcli/eslint-config": "^3.0.1", + "@npmcli/template-oss": "4.5.1", + "chalk": "^4.1.2", + "cli-progress": "^3.10.0", + "npmlog": "^6.0.1", "tap": "^16.0.1" }, - "files": [ - "bin/", - "lib/" - ], - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, "tap": { - "branches": 68, - "statements": 92, - "functions": 86, - "lines": 92, + "coverage-map": "map.js", "nyc-arg": [ "--exclude", "tap-snapshots/**" ] }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.21.3", - "publish": true + "version": "4.5.1" } } diff --git a/deps/npm/node_modules/read-package-json/LICENSE b/deps/npm/node_modules/read-package-json/LICENSE deleted file mode 100644 index 052085c436514a..00000000000000 --- a/deps/npm/node_modules/read-package-json/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. diff --git a/deps/npm/node_modules/read-package-json/lib/read-json.js b/deps/npm/node_modules/read-package-json/lib/read-json.js deleted file mode 100644 index d35f09ebd208f9..00000000000000 --- a/deps/npm/node_modules/read-package-json/lib/read-json.js +++ /dev/null @@ -1,589 +0,0 @@ -var fs = require('fs') - -var path = require('path') - -var { glob } = require('glob') -var normalizeData = require('normalize-package-data') -var safeJSON = require('json-parse-even-better-errors') -var util = require('util') -var normalizePackageBin = require('npm-normalize-package-bin') - -module.exports = readJson - -// put more stuff on here to customize. -readJson.extraSet = [ - bundleDependencies, - gypfile, - serverjs, - scriptpath, - authors, - readme, - mans, - bins, - githead, - fillTypes, -] - -var typoWarned = {} -var cache = {} - -function readJson (file, log_, strict_, cb_) { - var log, strict, cb - for (var i = 1; i < arguments.length - 1; i++) { - if (typeof arguments[i] === 'boolean') { - strict = arguments[i] - } else if (typeof arguments[i] === 'function') { - log = arguments[i] - } - } - - if (!log) { - log = function () {} - } - cb = arguments[arguments.length - 1] - - readJson_(file, log, strict, cb) -} - -function readJson_ (file, log, strict, cb) { - fs.readFile(file, 'utf8', function (er, d) { - parseJson(file, er, d, log, strict, cb) - }) -} - -function stripBOM (content) { - // Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) - // because the buffer-to-string conversion in `fs.readFileSync()` - // translates it to FEFF, the UTF-16 BOM. - if (content.charCodeAt(0) === 0xFEFF) { - content = content.slice(1) - } - return content -} - -function jsonClone (obj) { - if (obj == null) { - return obj - } else if (Array.isArray(obj)) { - var newarr = new Array(obj.length) - for (var ii in obj) { - newarr[ii] = jsonClone(obj[ii]) - } - return newarr - } else if (typeof obj === 'object') { - var newobj = {} - for (var kk in obj) { - newobj[kk] = jsonClone(obj[kk]) - } - return newobj - } else { - return obj - } -} - -function parseJson (file, er, d, log, strict, cb) { - if (er && er.code === 'ENOENT') { - return fs.stat(path.dirname(file), function (err, stat) { - if (!err && stat && !stat.isDirectory()) { - // ENOTDIR isn't used on Windows, but npm expects it. - er = Object.create(er) - er.code = 'ENOTDIR' - return cb(er) - } else { - return indexjs(file, er, log, strict, cb) - } - }) - } - if (er) { - return cb(er) - } - - if (cache[d]) { - return cb(null, jsonClone(cache[d])) - } - - var data - - try { - data = safeJSON(stripBOM(d)) - for (var key in data) { - if (/^_/.test(key)) { - delete data[key] - } - } - } catch (jsonErr) { - data = parseIndex(d) - if (!data) { - return cb(parseError(jsonErr, file)) - } - } - extrasCached(file, d, data, log, strict, cb) -} - -function extrasCached (file, d, data, log, strict, cb) { - extras(file, data, log, strict, function (err, extrasData) { - if (!err) { - cache[d] = jsonClone(extrasData) - } - cb(err, extrasData) - }) -} - -function indexjs (file, er, log, strict, cb) { - if (path.basename(file) === 'index.js') { - return cb(er) - } - - var index = path.resolve(path.dirname(file), 'index.js') - fs.readFile(index, 'utf8', function (er2, d) { - if (er2) { - return cb(er) - } - - if (cache[d]) { - return cb(null, cache[d]) - } - - var data = parseIndex(d) - if (!data) { - return cb(er) - } - - extrasCached(file, d, data, log, strict, cb) - }) -} - -readJson.extras = extras -function extras (file, data, log_, strict_, cb_) { - var log, strict, cb - for (var i = 2; i < arguments.length - 1; i++) { - if (typeof arguments[i] === 'boolean') { - strict = arguments[i] - } else if (typeof arguments[i] === 'function') { - log = arguments[i] - } - } - - if (!log) { - log = function () {} - } - cb = arguments[i] - - var set = readJson.extraSet - var n = set.length - var errState = null - set.forEach(function (fn) { - fn(file, data, then) - }) - - function then (er) { - if (errState) { - return - } - if (er) { - return cb(errState = er) - } - if (--n > 0) { - return - } - final(file, data, log, strict, cb) - } -} - -function scriptpath (file, data, cb) { - if (!data.scripts) { - return cb(null, data) - } - var k = Object.keys(data.scripts) - k.forEach(scriptpath_, data.scripts) - cb(null, data) -} - -function scriptpath_ (key) { - var s = this[key] - // This is never allowed, and only causes problems - if (typeof s !== 'string') { - return delete this[key] - } - - var spre = /^(\.[/\\])?node_modules[/\\].bin[\\/]/ - if (s.match(spre)) { - this[key] = this[key].replace(spre, '') - } -} - -function gypfile (file, data, cb) { - var dir = path.dirname(file) - var s = data.scripts || {} - if (s.install || s.preinstall) { - return cb(null, data) - } - - if (data.gypfile === false) { - return cb(null, data) - } - glob('*.gyp', { cwd: dir }) - .then(files => gypfile_(file, data, files, cb)) - .catch(er => cb(er)) -} - -function gypfile_ (file, data, files, cb) { - if (!files.length) { - return cb(null, data) - } - var s = data.scripts || {} - s.install = 'node-gyp rebuild' - data.scripts = s - data.gypfile = true - return cb(null, data) -} - -function serverjs (file, data, cb) { - var dir = path.dirname(file) - var s = data.scripts || {} - if (s.start) { - return cb(null, data) - } - fs.access(path.join(dir, 'server.js'), (err) => { - if (!err) { - s.start = 'node server.js' - data.scripts = s - } - return cb(null, data) - }) -} - -function authors (file, data, cb) { - if (data.contributors) { - return cb(null, data) - } - var af = path.resolve(path.dirname(file), 'AUTHORS') - fs.readFile(af, 'utf8', function (er, ad) { - // ignore error. just checking it. - if (er) { - return cb(null, data) - } - authors_(file, data, ad, cb) - }) -} - -function authors_ (file, data, ad, cb) { - ad = ad.split(/\r?\n/g).map(function (line) { - return line.replace(/^\s*#.*$/, '').trim() - }).filter(function (line) { - return line - }) - data.contributors = ad - return cb(null, data) -} - -function readme (file, data, cb) { - if (data.readme) { - return cb(null, data) - } - var dir = path.dirname(file) - var globOpts = { cwd: dir, nocase: true, mark: true } - glob('{README,README.*}', globOpts) - .then(files => { - // don't accept directories. - files = files.filter(function (filtered) { - return !filtered.match(/\/$/) - }) - if (!files.length) { - return cb() - } - var fn = preferMarkdownReadme(files) - var rm = path.resolve(dir, fn) - return readme_(file, data, rm, cb) - }) - .catch(er => cb(er)) -} - -function preferMarkdownReadme (files) { - var fallback = 0 - var re = /\.m?a?r?k?d?o?w?n?$/i - for (var i = 0; i < files.length; i++) { - if (files[i].match(re)) { - return files[i] - } else if (files[i].match(/README$/)) { - fallback = i - } - } - // prefer README.md, followed by README; otherwise, return - // the first filename (which could be README) - return files[fallback] -} - -function readme_ (file, data, rm, cb) { - var rmfn = path.basename(rm) - fs.readFile(rm, 'utf8', function (er, rmData) { - // maybe not readable, or something. - if (er) { - return cb() - } - data.readme = rmData - data.readmeFilename = rmfn - return cb(er, data) - }) -} - -function mans (file, data, cb) { - let cwd = data.directories && data.directories.man - if (data.man || !cwd) { - return cb(null, data) - } - const dirname = path.dirname(file) - cwd = path.resolve(path.dirname(file), cwd) - glob('**/*.[0-9]', { cwd }) - .then(mansGlob => { - data.man = mansGlob.map(man => - path.relative(dirname, path.join(cwd, man)).split(path.sep).join('/') - ) - return cb(null, data) - }) - .catch(er => cb(er)) -} - -function bins (file, data, cb) { - data = normalizePackageBin(data) - - var m = data.directories && data.directories.bin - if (data.bin || !m) { - return cb(null, data) - } - - m = path.resolve(path.dirname(file), path.join('.', path.join('/', m))) - glob('**', { cwd: m }) - .then(binsGlob => bins_(file, data, binsGlob, cb)) - .catch(er => cb(er)) -} - -function bins_ (file, data, binsGlob, cb) { - var m = (data.directories && data.directories.bin) || '.' - data.bin = binsGlob.reduce(function (acc, mf) { - if (mf && mf.charAt(0) !== '.') { - var f = path.basename(mf) - acc[f] = path.join(m, mf) - } - return acc - }, {}) - return cb(null, normalizePackageBin(data)) -} - -function bundleDependencies (file, data, cb) { - var bd = 'bundleDependencies' - var bdd = 'bundledDependencies' - // normalize key name - if (data[bdd] !== undefined) { - if (data[bd] === undefined) { - data[bd] = data[bdd] - } - delete data[bdd] - } - if (data[bd] === false) { - delete data[bd] - } else if (data[bd] === true) { - data[bd] = Object.keys(data.dependencies || {}) - } else if (data[bd] !== undefined && !Array.isArray(data[bd])) { - delete data[bd] - } - return cb(null, data) -} - -function githead (file, data, cb) { - if (data.gitHead) { - return cb(null, data) - } - var dir = path.dirname(file) - var head = path.resolve(dir, '.git/HEAD') - fs.readFile(head, 'utf8', function (er, headData) { - if (er) { - var parent = path.dirname(dir) - if (parent === dir) { - return cb(null, data) - } - return githead(dir, data, cb) - } - githead_(data, dir, headData, cb) - }) -} - -function githead_ (data, dir, head, cb) { - if (!head.match(/^ref: /)) { - data.gitHead = head.trim() - return cb(null, data) - } - var headRef = head.replace(/^ref: /, '').trim() - var headFile = path.resolve(dir, '.git', headRef) - fs.readFile(headFile, 'utf8', function (er, headData) { - if (er || !headData) { - var packFile = path.resolve(dir, '.git/packed-refs') - return fs.readFile(packFile, 'utf8', function (readFileErr, refs) { - if (readFileErr || !refs) { - return cb(null, data) - } - refs = refs.split('\n') - for (var i = 0; i < refs.length; i++) { - var match = refs[i].match(/^([0-9a-f]{40}) (.+)$/) - if (match && match[2].trim() === headRef) { - data.gitHead = match[1] - break - } - } - return cb(null, data) - }) - } - headData = headData.replace(/^ref: /, '').trim() - data.gitHead = headData - return cb(null, data) - }) -} - -/** - * Warn if the bin references don't point to anything. This might be better in - * normalize-package-data if it had access to the file path. - */ -function checkBinReferences_ (file, data, warn, cb) { - if (!(data.bin instanceof Object)) { - return cb() - } - - var keys = Object.keys(data.bin) - var keysLeft = keys.length - if (!keysLeft) { - return cb() - } - - function handleExists (relName, result) { - keysLeft-- - if (!result) { - warn('No bin file found at ' + relName) - } - if (!keysLeft) { - cb() - } - } - - keys.forEach(function (key) { - var dirName = path.dirname(file) - var relName = data.bin[key] - /* istanbul ignore if - impossible, bins have been normalized */ - if (typeof relName !== 'string') { - var msg = 'Bin filename for ' + key + - ' is not a string: ' + util.inspect(relName) - warn(msg) - delete data.bin[key] - handleExists(relName, true) - return - } - var binPath = path.resolve(dirName, relName) - fs.stat(binPath, (err) => handleExists(relName, !err)) - }) -} - -function final (file, data, log, strict, cb) { - var pId = makePackageId(data) - - function warn (msg) { - if (typoWarned[pId]) { - return - } - if (log) { - log('package.json', pId, msg) - } - } - - try { - normalizeData(data, warn, strict) - } catch (error) { - return cb(error) - } - - checkBinReferences_(file, data, warn, function () { - typoWarned[pId] = true - cb(null, data) - }) -} - -function fillTypes (file, data, cb) { - var index = data.main || 'index.js' - - if (typeof index !== 'string') { - return cb(new TypeError('The "main" attribute must be of type string.')) - } - - // TODO exports is much more complicated than this in verbose format - // We need to support for instance - - // "exports": { - // ".": [ - // { - // "default": "./lib/npm.js" - // }, - // "./lib/npm.js" - // ], - // "./package.json": "./package.json" - // }, - // as well as conditional exports - - // if (data.exports && typeof data.exports === 'string') { - // index = data.exports - // } - - // if (data.exports && data.exports['.']) { - // index = data.exports['.'] - // if (typeof index !== 'string') { - // } - // } - - var extless = - path.join(path.dirname(index), path.basename(index, path.extname(index))) - var dts = `./${extless}.d.ts` - var dtsPath = path.join(path.dirname(file), dts) - var hasDTSFields = 'types' in data || 'typings' in data - if (!hasDTSFields && fs.existsSync(dtsPath)) { - data.types = dts.split(path.sep).join('/') - } - - cb(null, data) -} - -function makePackageId (data) { - var name = cleanString(data.name) - var ver = cleanString(data.version) - return name + '@' + ver -} - -function cleanString (str) { - return (!str || typeof (str) !== 'string') ? '' : str.trim() -} - -// /**package { "name": "foo", "version": "1.2.3", ... } **/ -function parseIndex (data) { - data = data.split(/^\/\*\*package(?:\s|$)/m) - - if (data.length < 2) { - return null - } - data = data[1] - data = data.split(/\*\*\/$/m) - - if (data.length < 2) { - return null - } - data = data[0] - data = data.replace(/^\s*\*/mg, '') - - try { - return safeJSON(data) - } catch (er) { - return null - } -} - -function parseError (ex, file) { - var e = new Error('Failed to parse json\n' + ex.message) - e.code = 'EJSONPARSE' - e.path = file - return e -} diff --git a/deps/npm/node_modules/read-package-json/package.json b/deps/npm/node_modules/read-package-json/package.json deleted file mode 100644 index 01061f2bc27921..00000000000000 --- a/deps/npm/node_modules/read-package-json/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "read-package-json", - "version": "7.0.0", - "author": "GitHub Inc.", - "description": "The thing npm uses to read package.json files with semantics and defaults and validation", - "repository": { - "type": "git", - "url": "https://github.com/npm/read-package-json.git" - }, - "main": "lib/read-json.js", - "scripts": { - "prerelease": "npm t", - "postrelease": "npm publish && git push --follow-tags", - "release": "standard-version -s", - "test": "tap", - "npmclilint": "npmcli-lint", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", - "posttest": "npm run lint", - "postsnap": "npm run lintfix --", - "postlint": "template-oss-check", - "snap": "tap", - "template-oss-apply": "template-oss-apply --force" - }, - "dependencies": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "devDependencies": { - "@npmcli/eslint-config": "^4.0.0", - "@npmcli/template-oss": "4.18.0", - "tap": "^16.0.1" - }, - "license": "ISC", - "files": [ - "bin/", - "lib/" - ], - "engines": { - "node": "^16.14.0 || >=18.0.0" - }, - "tap": { - "branches": 73, - "functions": 77, - "lines": 77, - "statements": 77, - "nyc-arg": [ - "--exclude", - "tap-snapshots/**" - ] - }, - "templateOSS": { - "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.18.0", - "publish": "true", - "ciVersions": [ - "16.14.0", - "16.x", - "18.0.0", - "18.x" - ] - } -} diff --git a/deps/npm/node_modules/set-blocking/LICENSE.txt b/deps/npm/node_modules/set-blocking/LICENSE.txt deleted file mode 100644 index 836440bef7cf14..00000000000000 --- a/deps/npm/node_modules/set-blocking/LICENSE.txt +++ /dev/null @@ -1,14 +0,0 @@ -Copyright (c) 2016, 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/deps/npm/node_modules/set-blocking/index.js b/deps/npm/node_modules/set-blocking/index.js deleted file mode 100644 index 6f78774bb63ee6..00000000000000 --- a/deps/npm/node_modules/set-blocking/index.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = function (blocking) { - [process.stdout, process.stderr].forEach(function (stream) { - if (stream._handle && stream.isTTY && typeof stream._handle.setBlocking === 'function') { - stream._handle.setBlocking(blocking) - } - }) -} diff --git a/deps/npm/node_modules/set-blocking/package.json b/deps/npm/node_modules/set-blocking/package.json deleted file mode 100644 index c082db72c6259d..00000000000000 --- a/deps/npm/node_modules/set-blocking/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "set-blocking", - "version": "2.0.0", - "description": "set blocking stdio and stderr ensuring that terminal output does not truncate", - "main": "index.js", - "scripts": { - "pretest": "standard", - "test": "nyc mocha ./test/*.js", - "coverage": "nyc report --reporter=text-lcov | coveralls", - "version": "standard-version" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/yargs/set-blocking.git" - }, - "keywords": [ - "flush", - "terminal", - "blocking", - "shim", - "stdio", - "stderr" - ], - "author": "Ben Coe ", - "license": "ISC", - "bugs": { - "url": "https://github.com/yargs/set-blocking/issues" - }, - "homepage": "https://github.com/yargs/set-blocking#readme", - "devDependencies": { - "chai": "^3.5.0", - "coveralls": "^2.11.9", - "mocha": "^2.4.5", - "nyc": "^6.4.4", - "standard": "^7.0.1", - "standard-version": "^2.2.1" - }, - "files": [ - "index.js", - "LICENSE.txt" - ] -} \ No newline at end of file diff --git a/deps/npm/node_modules/ip-address/node_modules/sprintf-js/CONTRIBUTORS.md b/deps/npm/node_modules/sprintf-js/CONTRIBUTORS.md similarity index 100% rename from deps/npm/node_modules/ip-address/node_modules/sprintf-js/CONTRIBUTORS.md rename to deps/npm/node_modules/sprintf-js/CONTRIBUTORS.md diff --git a/deps/npm/node_modules/ip-address/node_modules/sprintf-js/LICENSE b/deps/npm/node_modules/sprintf-js/LICENSE similarity index 100% rename from deps/npm/node_modules/ip-address/node_modules/sprintf-js/LICENSE rename to deps/npm/node_modules/sprintf-js/LICENSE diff --git a/deps/npm/node_modules/sprintf-js/bower.json b/deps/npm/node_modules/sprintf-js/bower.json new file mode 100644 index 00000000000000..d90a75989f7b05 --- /dev/null +++ b/deps/npm/node_modules/sprintf-js/bower.json @@ -0,0 +1,14 @@ +{ + "name": "sprintf", + "description": "JavaScript sprintf implementation", + "version": "1.0.3", + "main": "src/sprintf.js", + "license": "BSD-3-Clause-Clear", + "keywords": ["sprintf", "string", "formatting"], + "authors": ["Alexandru Marasteanu (http://alexei.ro/)"], + "homepage": "https://github.com/alexei/sprintf.js", + "repository": { + "type": "git", + "url": "git://github.com/alexei/sprintf.js.git" + } +} diff --git a/deps/npm/node_modules/sprintf-js/demo/angular.html b/deps/npm/node_modules/sprintf-js/demo/angular.html new file mode 100644 index 00000000000000..3559efd7635634 --- /dev/null +++ b/deps/npm/node_modules/sprintf-js/demo/angular.html @@ -0,0 +1,20 @@ + + + + + + + + +
    {{ "%+010d"|sprintf:-123 }}
    +
    {{ "%+010d"|vsprintf:[-123] }}
    +
    {{ "%+010d"|fmt:-123 }}
    +
    {{ "%+010d"|vfmt:[-123] }}
    +
    {{ "I've got %2$d apples and %1$d oranges."|fmt:4:2 }}
    +
    {{ "I've got %(apples)d apples and %(oranges)d oranges."|fmt:{apples: 2, oranges: 4} }}
    + + + + diff --git a/deps/npm/node_modules/ip-address/node_modules/sprintf-js/dist/.gitattributes b/deps/npm/node_modules/sprintf-js/dist/.gitattributes similarity index 100% rename from deps/npm/node_modules/ip-address/node_modules/sprintf-js/dist/.gitattributes rename to deps/npm/node_modules/sprintf-js/dist/.gitattributes diff --git a/deps/npm/node_modules/ip-address/node_modules/sprintf-js/dist/angular-sprintf.min.js b/deps/npm/node_modules/sprintf-js/dist/angular-sprintf.min.js similarity index 100% rename from deps/npm/node_modules/ip-address/node_modules/sprintf-js/dist/angular-sprintf.min.js rename to deps/npm/node_modules/sprintf-js/dist/angular-sprintf.min.js diff --git a/deps/npm/node_modules/ip-address/node_modules/sprintf-js/dist/sprintf.min.js b/deps/npm/node_modules/sprintf-js/dist/sprintf.min.js similarity index 100% rename from deps/npm/node_modules/ip-address/node_modules/sprintf-js/dist/sprintf.min.js rename to deps/npm/node_modules/sprintf-js/dist/sprintf.min.js diff --git a/deps/npm/node_modules/sprintf-js/gruntfile.js b/deps/npm/node_modules/sprintf-js/gruntfile.js new file mode 100644 index 00000000000000..246e1c3b9801fc --- /dev/null +++ b/deps/npm/node_modules/sprintf-js/gruntfile.js @@ -0,0 +1,36 @@ +module.exports = function(grunt) { + grunt.initConfig({ + pkg: grunt.file.readJSON("package.json"), + + uglify: { + options: { + banner: "/*! <%= pkg.name %> | <%= pkg.author %> | <%= pkg.license %> */\n", + sourceMap: true + }, + build: { + files: [ + { + src: "src/sprintf.js", + dest: "dist/sprintf.min.js" + }, + { + src: "src/angular-sprintf.js", + dest: "dist/angular-sprintf.min.js" + } + ] + } + }, + + watch: { + js: { + files: "src/*.js", + tasks: ["uglify"] + } + } + }) + + grunt.loadNpmTasks("grunt-contrib-uglify") + grunt.loadNpmTasks("grunt-contrib-watch") + + grunt.registerTask("default", ["uglify", "watch"]) +} diff --git a/deps/npm/node_modules/ip-address/node_modules/sprintf-js/package.json b/deps/npm/node_modules/sprintf-js/package.json similarity index 100% rename from deps/npm/node_modules/ip-address/node_modules/sprintf-js/package.json rename to deps/npm/node_modules/sprintf-js/package.json diff --git a/deps/npm/node_modules/ip-address/node_modules/sprintf-js/src/angular-sprintf.js b/deps/npm/node_modules/sprintf-js/src/angular-sprintf.js similarity index 100% rename from deps/npm/node_modules/ip-address/node_modules/sprintf-js/src/angular-sprintf.js rename to deps/npm/node_modules/sprintf-js/src/angular-sprintf.js diff --git a/deps/npm/node_modules/ip-address/node_modules/sprintf-js/src/sprintf.js b/deps/npm/node_modules/sprintf-js/src/sprintf.js similarity index 100% rename from deps/npm/node_modules/ip-address/node_modules/sprintf-js/src/sprintf.js rename to deps/npm/node_modules/sprintf-js/src/sprintf.js diff --git a/deps/npm/node_modules/sprintf-js/test/test.js b/deps/npm/node_modules/sprintf-js/test/test.js new file mode 100644 index 00000000000000..6f57b2538c8522 --- /dev/null +++ b/deps/npm/node_modules/sprintf-js/test/test.js @@ -0,0 +1,82 @@ +var assert = require("assert"), + sprintfjs = require("../src/sprintf.js"), + sprintf = sprintfjs.sprintf, + vsprintf = sprintfjs.vsprintf + +describe("sprintfjs", function() { + var pi = 3.141592653589793 + + it("should return formated strings for simple placeholders", function() { + assert.equal("%", sprintf("%%")) + assert.equal("10", sprintf("%b", 2)) + assert.equal("A", sprintf("%c", 65)) + assert.equal("2", sprintf("%d", 2)) + assert.equal("2", sprintf("%i", 2)) + assert.equal("2", sprintf("%d", "2")) + assert.equal("2", sprintf("%i", "2")) + assert.equal('{"foo":"bar"}', sprintf("%j", {foo: "bar"})) + assert.equal('["foo","bar"]', sprintf("%j", ["foo", "bar"])) + assert.equal("2e+0", sprintf("%e", 2)) + assert.equal("2", sprintf("%u", 2)) + assert.equal("4294967294", sprintf("%u", -2)) + assert.equal("2.2", sprintf("%f", 2.2)) + assert.equal("3.141592653589793", sprintf("%g", pi)) + assert.equal("10", sprintf("%o", 8)) + assert.equal("%s", sprintf("%s", "%s")) + assert.equal("ff", sprintf("%x", 255)) + assert.equal("FF", sprintf("%X", 255)) + assert.equal("Polly wants a cracker", sprintf("%2$s %3$s a %1$s", "cracker", "Polly", "wants")) + assert.equal("Hello world!", sprintf("Hello %(who)s!", {"who": "world"})) + }) + + it("should return formated strings for complex placeholders", function() { + // sign + assert.equal("2", sprintf("%d", 2)) + assert.equal("-2", sprintf("%d", -2)) + assert.equal("+2", sprintf("%+d", 2)) + assert.equal("-2", sprintf("%+d", -2)) + assert.equal("2", sprintf("%i", 2)) + assert.equal("-2", sprintf("%i", -2)) + assert.equal("+2", sprintf("%+i", 2)) + assert.equal("-2", sprintf("%+i", -2)) + assert.equal("2.2", sprintf("%f", 2.2)) + assert.equal("-2.2", sprintf("%f", -2.2)) + assert.equal("+2.2", sprintf("%+f", 2.2)) + assert.equal("-2.2", sprintf("%+f", -2.2)) + assert.equal("-2.3", sprintf("%+.1f", -2.34)) + assert.equal("-0.0", sprintf("%+.1f", -0.01)) + assert.equal("3.14159", sprintf("%.6g", pi)) + assert.equal("3.14", sprintf("%.3g", pi)) + assert.equal("3", sprintf("%.1g", pi)) + assert.equal("-000000123", sprintf("%+010d", -123)) + assert.equal("______-123", sprintf("%+'_10d", -123)) + assert.equal("-234.34 123.2", sprintf("%f %f", -234.34, 123.2)) + + // padding + assert.equal("-0002", sprintf("%05d", -2)) + assert.equal("-0002", sprintf("%05i", -2)) + assert.equal(" <", sprintf("%5s", "<")) + assert.equal("0000<", sprintf("%05s", "<")) + assert.equal("____<", sprintf("%'_5s", "<")) + assert.equal("> ", sprintf("%-5s", ">")) + assert.equal(">0000", sprintf("%0-5s", ">")) + assert.equal(">____", sprintf("%'_-5s", ">")) + assert.equal("xxxxxx", sprintf("%5s", "xxxxxx")) + assert.equal("1234", sprintf("%02u", 1234)) + assert.equal(" -10.235", sprintf("%8.3f", -10.23456)) + assert.equal("-12.34 xxx", sprintf("%f %s", -12.34, "xxx")) + assert.equal('{\n "foo": "bar"\n}', sprintf("%2j", {foo: "bar"})) + assert.equal('[\n "foo",\n "bar"\n]', sprintf("%2j", ["foo", "bar"])) + + // precision + assert.equal("2.3", sprintf("%.1f", 2.345)) + assert.equal("xxxxx", sprintf("%5.5s", "xxxxxx")) + assert.equal(" x", sprintf("%5.1s", "xxxxxx")) + + }) + + it("should return formated strings for callbacks", function() { + assert.equal("foobar", sprintf("%s", function() { return "foobar" })) + assert.equal(Date.now(), sprintf("%s", Date.now)) // should pass... + }) +}) diff --git a/deps/npm/node_modules/wcwidth/LICENSE b/deps/npm/node_modules/wcwidth/LICENSE deleted file mode 100644 index 313ef1e888e41b..00000000000000 --- a/deps/npm/node_modules/wcwidth/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ -wcwidth.js: JavaScript Portng of Markus Kuhn's wcwidth() Implementation -======================================================================= - -Copyright (C) 2012 by Jun Woong. - -This package is a JavaScript porting of `wcwidth()` implementation -[by Markus Kuhn](http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c). - -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. - - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - diff --git a/deps/npm/node_modules/wcwidth/combining.js b/deps/npm/node_modules/wcwidth/combining.js deleted file mode 100644 index dac9789d35f0f1..00000000000000 --- a/deps/npm/node_modules/wcwidth/combining.js +++ /dev/null @@ -1,50 +0,0 @@ -module.exports = [ - [ 0x0300, 0x036F ], [ 0x0483, 0x0486 ], [ 0x0488, 0x0489 ], - [ 0x0591, 0x05BD ], [ 0x05BF, 0x05BF ], [ 0x05C1, 0x05C2 ], - [ 0x05C4, 0x05C5 ], [ 0x05C7, 0x05C7 ], [ 0x0600, 0x0603 ], - [ 0x0610, 0x0615 ], [ 0x064B, 0x065E ], [ 0x0670, 0x0670 ], - [ 0x06D6, 0x06E4 ], [ 0x06E7, 0x06E8 ], [ 0x06EA, 0x06ED ], - [ 0x070F, 0x070F ], [ 0x0711, 0x0711 ], [ 0x0730, 0x074A ], - [ 0x07A6, 0x07B0 ], [ 0x07EB, 0x07F3 ], [ 0x0901, 0x0902 ], - [ 0x093C, 0x093C ], [ 0x0941, 0x0948 ], [ 0x094D, 0x094D ], - [ 0x0951, 0x0954 ], [ 0x0962, 0x0963 ], [ 0x0981, 0x0981 ], - [ 0x09BC, 0x09BC ], [ 0x09C1, 0x09C4 ], [ 0x09CD, 0x09CD ], - [ 0x09E2, 0x09E3 ], [ 0x0A01, 0x0A02 ], [ 0x0A3C, 0x0A3C ], - [ 0x0A41, 0x0A42 ], [ 0x0A47, 0x0A48 ], [ 0x0A4B, 0x0A4D ], - [ 0x0A70, 0x0A71 ], [ 0x0A81, 0x0A82 ], [ 0x0ABC, 0x0ABC ], - [ 0x0AC1, 0x0AC5 ], [ 0x0AC7, 0x0AC8 ], [ 0x0ACD, 0x0ACD ], - [ 0x0AE2, 0x0AE3 ], [ 0x0B01, 0x0B01 ], [ 0x0B3C, 0x0B3C ], - [ 0x0B3F, 0x0B3F ], [ 0x0B41, 0x0B43 ], [ 0x0B4D, 0x0B4D ], - [ 0x0B56, 0x0B56 ], [ 0x0B82, 0x0B82 ], [ 0x0BC0, 0x0BC0 ], - [ 0x0BCD, 0x0BCD ], [ 0x0C3E, 0x0C40 ], [ 0x0C46, 0x0C48 ], - [ 0x0C4A, 0x0C4D ], [ 0x0C55, 0x0C56 ], [ 0x0CBC, 0x0CBC ], - [ 0x0CBF, 0x0CBF ], [ 0x0CC6, 0x0CC6 ], [ 0x0CCC, 0x0CCD ], - [ 0x0CE2, 0x0CE3 ], [ 0x0D41, 0x0D43 ], [ 0x0D4D, 0x0D4D ], - [ 0x0DCA, 0x0DCA ], [ 0x0DD2, 0x0DD4 ], [ 0x0DD6, 0x0DD6 ], - [ 0x0E31, 0x0E31 ], [ 0x0E34, 0x0E3A ], [ 0x0E47, 0x0E4E ], - [ 0x0EB1, 0x0EB1 ], [ 0x0EB4, 0x0EB9 ], [ 0x0EBB, 0x0EBC ], - [ 0x0EC8, 0x0ECD ], [ 0x0F18, 0x0F19 ], [ 0x0F35, 0x0F35 ], - [ 0x0F37, 0x0F37 ], [ 0x0F39, 0x0F39 ], [ 0x0F71, 0x0F7E ], - [ 0x0F80, 0x0F84 ], [ 0x0F86, 0x0F87 ], [ 0x0F90, 0x0F97 ], - [ 0x0F99, 0x0FBC ], [ 0x0FC6, 0x0FC6 ], [ 0x102D, 0x1030 ], - [ 0x1032, 0x1032 ], [ 0x1036, 0x1037 ], [ 0x1039, 0x1039 ], - [ 0x1058, 0x1059 ], [ 0x1160, 0x11FF ], [ 0x135F, 0x135F ], - [ 0x1712, 0x1714 ], [ 0x1732, 0x1734 ], [ 0x1752, 0x1753 ], - [ 0x1772, 0x1773 ], [ 0x17B4, 0x17B5 ], [ 0x17B7, 0x17BD ], - [ 0x17C6, 0x17C6 ], [ 0x17C9, 0x17D3 ], [ 0x17DD, 0x17DD ], - [ 0x180B, 0x180D ], [ 0x18A9, 0x18A9 ], [ 0x1920, 0x1922 ], - [ 0x1927, 0x1928 ], [ 0x1932, 0x1932 ], [ 0x1939, 0x193B ], - [ 0x1A17, 0x1A18 ], [ 0x1B00, 0x1B03 ], [ 0x1B34, 0x1B34 ], - [ 0x1B36, 0x1B3A ], [ 0x1B3C, 0x1B3C ], [ 0x1B42, 0x1B42 ], - [ 0x1B6B, 0x1B73 ], [ 0x1DC0, 0x1DCA ], [ 0x1DFE, 0x1DFF ], - [ 0x200B, 0x200F ], [ 0x202A, 0x202E ], [ 0x2060, 0x2063 ], - [ 0x206A, 0x206F ], [ 0x20D0, 0x20EF ], [ 0x302A, 0x302F ], - [ 0x3099, 0x309A ], [ 0xA806, 0xA806 ], [ 0xA80B, 0xA80B ], - [ 0xA825, 0xA826 ], [ 0xFB1E, 0xFB1E ], [ 0xFE00, 0xFE0F ], - [ 0xFE20, 0xFE23 ], [ 0xFEFF, 0xFEFF ], [ 0xFFF9, 0xFFFB ], - [ 0x10A01, 0x10A03 ], [ 0x10A05, 0x10A06 ], [ 0x10A0C, 0x10A0F ], - [ 0x10A38, 0x10A3A ], [ 0x10A3F, 0x10A3F ], [ 0x1D167, 0x1D169 ], - [ 0x1D173, 0x1D182 ], [ 0x1D185, 0x1D18B ], [ 0x1D1AA, 0x1D1AD ], - [ 0x1D242, 0x1D244 ], [ 0xE0001, 0xE0001 ], [ 0xE0020, 0xE007F ], - [ 0xE0100, 0xE01EF ] -] diff --git a/deps/npm/node_modules/wcwidth/docs/index.md b/deps/npm/node_modules/wcwidth/docs/index.md deleted file mode 100644 index 5c5126d03287b4..00000000000000 --- a/deps/npm/node_modules/wcwidth/docs/index.md +++ /dev/null @@ -1,65 +0,0 @@ -### Javascript porting of Markus Kuhn's wcwidth() implementation - -The following explanation comes from the original C implementation: - -This is an implementation of wcwidth() and wcswidth() (defined in -IEEE Std 1002.1-2001) for Unicode. - -http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html -http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html - -In fixed-width output devices, Latin characters all occupy a single -"cell" position of equal width, whereas ideographic CJK characters -occupy two such cells. Interoperability between terminal-line -applications and (teletype-style) character terminals using the -UTF-8 encoding requires agreement on which character should advance -the cursor by how many cell positions. No established formal -standards exist at present on which Unicode character shall occupy -how many cell positions on character terminals. These routines are -a first attempt of defining such behavior based on simple rules -applied to data provided by the Unicode Consortium. - -For some graphical characters, the Unicode standard explicitly -defines a character-cell width via the definition of the East Asian -FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes. -In all these cases, there is no ambiguity about which width a -terminal shall use. For characters in the East Asian Ambiguous (A) -class, the width choice depends purely on a preference of backward -compatibility with either historic CJK or Western practice. -Choosing single-width for these characters is easy to justify as -the appropriate long-term solution, as the CJK practice of -displaying these characters as double-width comes from historic -implementation simplicity (8-bit encoded characters were displayed -single-width and 16-bit ones double-width, even for Greek, -Cyrillic, etc.) and not any typographic considerations. - -Much less clear is the choice of width for the Not East Asian -(Neutral) class. Existing practice does not dictate a width for any -of these characters. It would nevertheless make sense -typographically to allocate two character cells to characters such -as for instance EM SPACE or VOLUME INTEGRAL, which cannot be -represented adequately with a single-width glyph. The following -routines at present merely assign a single-cell width to all -neutral characters, in the interest of simplicity. This is not -entirely satisfactory and should be reconsidered before -establishing a formal standard in this area. At the moment, the -decision which Not East Asian (Neutral) characters should be -represented by double-width glyphs cannot yet be answered by -applying a simple rule from the Unicode database content. Setting -up a proper standard for the behavior of UTF-8 character terminals -will require a careful analysis not only of each Unicode character, -but also of each presentation form, something the author of these -routines has avoided to do so far. - -http://www.unicode.org/unicode/reports/tr11/ - -Markus Kuhn -- 2007-05-26 (Unicode 5.0) - -Permission to use, copy, modify, and distribute this software -for any purpose and without fee is hereby granted. The author -disclaims all warranties with regard to this software. - -Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c - - - diff --git a/deps/npm/node_modules/wcwidth/index.js b/deps/npm/node_modules/wcwidth/index.js deleted file mode 100644 index 48cbb6020aebe9..00000000000000 --- a/deps/npm/node_modules/wcwidth/index.js +++ /dev/null @@ -1,99 +0,0 @@ -"use strict" - -var defaults = require('defaults') -var combining = require('./combining') - -var DEFAULTS = { - nul: 0, - control: 0 -} - -module.exports = function wcwidth(str) { - return wcswidth(str, DEFAULTS) -} - -module.exports.config = function(opts) { - opts = defaults(opts || {}, DEFAULTS) - return function wcwidth(str) { - return wcswidth(str, opts) - } -} - -/* - * The following functions define the column width of an ISO 10646 - * character as follows: - * - The null character (U+0000) has a column width of 0. - * - Other C0/C1 control characters and DEL will lead to a return value - * of -1. - * - Non-spacing and enclosing combining characters (general category - * code Mn or Me in the - * Unicode database) have a column width of 0. - * - SOFT HYPHEN (U+00AD) has a column width of 1. - * - Other format characters (general category code Cf in the Unicode - * database) and ZERO WIDTH - * SPACE (U+200B) have a column width of 0. - * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) - * have a column width of 0. - * - Spacing characters in the East Asian Wide (W) or East Asian - * Full-width (F) category as - * defined in Unicode Technical Report #11 have a column width of 2. - * - All remaining characters (including all printable ISO 8859-1 and - * WGL4 characters, Unicode control characters, etc.) have a column - * width of 1. - * This implementation assumes that characters are encoded in ISO 10646. -*/ - -function wcswidth(str, opts) { - if (typeof str !== 'string') return wcwidth(str, opts) - - var s = 0 - for (var i = 0; i < str.length; i++) { - var n = wcwidth(str.charCodeAt(i), opts) - if (n < 0) return -1 - s += n - } - - return s -} - -function wcwidth(ucs, opts) { - // test for 8-bit control characters - if (ucs === 0) return opts.nul - if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) return opts.control - - // binary search in table of non-spacing characters - if (bisearch(ucs)) return 0 - - // if we arrive here, ucs is not a combining or C0/C1 control character - return 1 + - (ucs >= 0x1100 && - (ucs <= 0x115f || // Hangul Jamo init. consonants - ucs == 0x2329 || ucs == 0x232a || - (ucs >= 0x2e80 && ucs <= 0xa4cf && - ucs != 0x303f) || // CJK ... Yi - (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables - (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compatibility Ideographs - (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms - (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compatibility Forms - (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms - (ucs >= 0xffe0 && ucs <= 0xffe6) || - (ucs >= 0x20000 && ucs <= 0x2fffd) || - (ucs >= 0x30000 && ucs <= 0x3fffd))); -} - -function bisearch(ucs) { - var min = 0 - var max = combining.length - 1 - var mid - - if (ucs < combining[0][0] || ucs > combining[max][1]) return false - - while (max >= min) { - mid = Math.floor((min + max) / 2) - if (ucs > combining[mid][1]) min = mid + 1 - else if (ucs < combining[mid][0]) max = mid - 1 - else return true - } - - return false -} diff --git a/deps/npm/node_modules/wcwidth/package.json b/deps/npm/node_modules/wcwidth/package.json deleted file mode 100644 index eb2df9d0076d20..00000000000000 --- a/deps/npm/node_modules/wcwidth/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "wcwidth", - "version": "1.0.1", - "description": "Port of C's wcwidth() and wcswidth()", - "author": "Tim Oxley", - "contributors": [ - "Woong Jun (http://code.woong.org/)" - ], - "main": "index.js", - "dependencies": { - "defaults": "^1.0.3" - }, - "devDependencies": { - "tape": "^4.5.1" - }, - "license": "MIT", - "keywords": [ - "wide character", - "wc", - "wide character string", - "wcs", - "terminal", - "width", - "wcwidth", - "wcswidth" - ], - "directories": { - "doc": "docs", - "test": "test" - }, - "scripts": { - "test": "tape test/*.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/timoxley/wcwidth.git" - }, - "bugs": { - "url": "https://github.com/timoxley/wcwidth/issues" - }, - "homepage": "https://github.com/timoxley/wcwidth#readme" -} diff --git a/deps/npm/node_modules/wcwidth/test/index.js b/deps/npm/node_modules/wcwidth/test/index.js deleted file mode 100644 index 5180599a2ff285..00000000000000 --- a/deps/npm/node_modules/wcwidth/test/index.js +++ /dev/null @@ -1,64 +0,0 @@ -"use strict" - -var wcwidth = require('../') -var test = require('tape') - -test('handles regular strings', function(t) { - t.strictEqual(wcwidth('abc'), 3) - t.end() -}) - -test('handles multibyte strings', function(t) { - t.strictEqual(wcwidth('字的模块'), 8) - t.end() -}) - -test('handles multibyte characters mixed with regular characters', function(t) { - t.strictEqual(wcwidth('abc 字的模块'), 12) - t.end() -}) - -test('ignores control characters e.g. \\n', function(t) { - t.strictEqual(wcwidth('abc\n字的模块\ndef'), 14) - t.end() -}) - -test('ignores bad input', function(t) { - t.strictEqual(wcwidth(''), 0) - t.strictEqual(wcwidth(3), 0) - t.strictEqual(wcwidth({}), 0) - t.strictEqual(wcwidth([]), 0) - t.strictEqual(wcwidth(), 0) - t.end() -}) - -test('ignores nul (charcode 0)', function(t) { - t.strictEqual(wcwidth(String.fromCharCode(0)), 0) - t.end() -}) - -test('ignores nul mixed with chars', function(t) { - t.strictEqual(wcwidth('a' + String.fromCharCode(0) + '\n字的'), 5) - t.end() -}) - -test('can have custom value for nul', function(t) { - t.strictEqual(wcwidth.config({ - nul: 10 - })(String.fromCharCode(0) + 'a字的'), 15) - t.end() -}) - -test('can have custom control char value', function(t) { - t.strictEqual(wcwidth.config({ - control: 1 - })('abc\n字的模块\ndef'), 16) - t.end() -}) - -test('negative custom control chars == -1', function(t) { - t.strictEqual(wcwidth.config({ - control: -1 - })('abc\n字的模块\ndef'), -1) - t.end() -}) diff --git a/deps/npm/node_modules/wide-align/LICENSE b/deps/npm/node_modules/wide-align/LICENSE deleted file mode 100755 index f4be44d881b2d9..00000000000000 --- a/deps/npm/node_modules/wide-align/LICENSE +++ /dev/null @@ -1,14 +0,0 @@ -Copyright (c) 2015, Rebecca Turner - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/deps/npm/node_modules/wide-align/align.js b/deps/npm/node_modules/wide-align/align.js deleted file mode 100755 index 4f94ca4cde19b5..00000000000000 --- a/deps/npm/node_modules/wide-align/align.js +++ /dev/null @@ -1,65 +0,0 @@ -'use strict' -var stringWidth = require('string-width') - -exports.center = alignCenter -exports.left = alignLeft -exports.right = alignRight - -// lodash's way of generating pad characters. - -function createPadding (width) { - var result = '' - var string = ' ' - var n = width - do { - if (n % 2) { - result += string; - } - n = Math.floor(n / 2); - string += string; - } while (n); - - return result; -} - -function alignLeft (str, width) { - var trimmed = str.trimRight() - if (trimmed.length === 0 && str.length >= width) return str - var padding = '' - var strWidth = stringWidth(trimmed) - - if (strWidth < width) { - padding = createPadding(width - strWidth) - } - - return trimmed + padding -} - -function alignRight (str, width) { - var trimmed = str.trimLeft() - if (trimmed.length === 0 && str.length >= width) return str - var padding = '' - var strWidth = stringWidth(trimmed) - - if (strWidth < width) { - padding = createPadding(width - strWidth) - } - - return padding + trimmed -} - -function alignCenter (str, width) { - var trimmed = str.trim() - if (trimmed.length === 0 && str.length >= width) return str - var padLeft = '' - var padRight = '' - var strWidth = stringWidth(trimmed) - - if (strWidth < width) { - var padLeftBy = parseInt((width - strWidth) / 2, 10) - padLeft = createPadding(padLeftBy) - padRight = createPadding(width - (strWidth + padLeftBy)) - } - - return padLeft + trimmed + padRight -} diff --git a/deps/npm/node_modules/wide-align/package.json b/deps/npm/node_modules/wide-align/package.json deleted file mode 100755 index 2dd27074c77770..00000000000000 --- a/deps/npm/node_modules/wide-align/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "wide-align", - "version": "1.1.5", - "description": "A wide-character aware text alignment function for use on the console or with fixed width fonts.", - "main": "align.js", - "scripts": { - "test": "tap --coverage test/*.js" - }, - "keywords": [ - "wide", - "double", - "unicode", - "cjkv", - "pad", - "align" - ], - "author": "Rebecca Turner (http://re-becca.org/)", - "license": "ISC", - "repository": { - "type": "git", - "url": "https://github.com/iarna/wide-align" - }, - "//": "But not version 5 of string-width, as that's ESM only", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - }, - "devDependencies": { - "tap": "*" - }, - "files": [ - "align.js" - ] -} diff --git a/deps/npm/package.json b/deps/npm/package.json index d157883a10bbc7..1aae41fbe75769 100644 --- a/deps/npm/package.json +++ b/deps/npm/package.json @@ -1,5 +1,5 @@ { - "version": "10.5.2", + "version": "10.7.0", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [ @@ -27,7 +27,7 @@ "author": "GitHub Inc.", "repository": { "type": "git", - "url": "https://github.com/npm/cli.git" + "url": "git+https://github.com/npm/cli.git" }, "bugs": { "url": "https://github.com/npm/cli/issues" @@ -56,10 +56,10 @@ "@npmcli/config": "^8.0.2", "@npmcli/fs": "^3.1.0", "@npmcli/map-workspaces": "^3.0.6", - "@npmcli/package-json": "^5.0.2", + "@npmcli/package-json": "^5.1.0", "@npmcli/promise-spawn": "^7.0.1", - "@npmcli/redact": "^1.1.0", - "@npmcli/run-script": "^7.0.4", + "@npmcli/redact": "^2.0.0", + "@npmcli/run-script": "^8.1.0", "@sigstore/tuf": "^2.3.2", "abbrev": "^2.0.0", "archy": "~1.0.0", @@ -67,8 +67,6 @@ "chalk": "^5.3.0", "ci-info": "^4.0.0", "cli-columns": "^4.0.0", - "cli-table3": "^0.6.4", - "columnify": "^1.6.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", "glob": "^10.3.12", @@ -80,16 +78,16 @@ "json-parse-even-better-errors": "^3.0.1", "libnpmaccess": "^8.0.1", "libnpmdiff": "^6.0.3", - "libnpmexec": "^7.0.4", + "libnpmexec": "^8.0.0", "libnpmfund": "^5.0.1", "libnpmhook": "^10.0.0", "libnpmorg": "^6.0.1", - "libnpmpack": "^6.0.3", + "libnpmpack": "^7.0.0", "libnpmpublish": "^9.0.2", "libnpmsearch": "^7.0.0", "libnpmteam": "^6.0.0", - "libnpmversion": "^5.0.1", - "make-fetch-happen": "^13.0.0", + "libnpmversion": "^6.0.0", + "make-fetch-happen": "^13.0.1", "minimatch": "^9.0.4", "minipass": "^7.0.4", "minipass-pipeline": "^1.2.4", @@ -99,16 +97,15 @@ "normalize-package-data": "^6.0.0", "npm-audit-report": "^5.0.0", "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.1", + "npm-package-arg": "^11.0.2", "npm-pick-manifest": "^9.0.0", - "npm-profile": "^9.0.0", - "npm-registry-fetch": "^16.2.0", + "npm-profile": "^9.0.2", + "npm-registry-fetch": "^17.0.0", "npm-user-validate": "^2.0.0", - "npmlog": "^7.0.1", "p-map": "^4.0.0", - "pacote": "^17.0.6", + "pacote": "^18.0.3", "parse-conflict-json": "^3.0.1", - "proc-log": "^3.0.0", + "proc-log": "^4.2.0", "qrcode-terminal": "^0.12.0", "read": "^3.0.1", "semver": "^7.6.0", @@ -140,8 +137,6 @@ "chalk", "ci-info", "cli-columns", - "cli-table3", - "columnify", "fastest-levenshtein", "fs-minipass", "glob", @@ -177,7 +172,6 @@ "npm-profile", "npm-registry-fetch", "npm-user-validate", - "npmlog", "p-map", "pacote", "parse-conflict-json", @@ -199,7 +193,7 @@ "devDependencies": { "@npmcli/docs": "^1.0.0", "@npmcli/eslint-config": "^4.0.2", - "@npmcli/git": "^5.0.5", + "@npmcli/git": "^5.0.6", "@npmcli/mock-globals": "^1.0.0", "@npmcli/mock-registry": "^1.0.0", "@npmcli/template-oss": "4.21.3", @@ -207,20 +201,21 @@ "ajv": "^8.12.0", "ajv-formats": "^2.1.1", "ajv-formats-draft2019": "^1.6.1", + "cli-table3": "^0.6.4", "diff": "^5.2.0", - "licensee": "^10.0.0", "nock": "^13.4.0", "npm-packlist": "^8.0.2", "remark": "^14.0.2", "remark-gfm": "^3.0.1", "remark-github": "^11.2.4", + "rimraf": "^5.0.5", "spawk": "^1.7.1", "tap": "^16.3.9" }, "scripts": { "dependencies": "node scripts/bundle-and-gitignore-deps.js && node scripts/dependency-graph.js", "dumpconf": "env | grep npm | sort | uniq", - "licenses": "licensee --production --errors-only", + "licenses": "npx licensee --production --errors-only", "test": "tap", "test:nocolor": "CI=true tap -Rclassic", "test-all": "node . run test -ws -iwr --if-present", diff --git a/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs b/deps/npm/tap-snapshots/test/lib/cli/exit-handler.js.test.cjs similarity index 63% rename from deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs rename to deps/npm/tap-snapshots/test/lib/cli/exit-handler.js.test.cjs index 3e7bc4570dd4ad..cedb56642f26d7 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/cli/exit-handler.js.test.cjs @@ -5,63 +5,62 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' -exports[`test/lib/utils/exit-handler.js TAP handles unknown error with logs and debug file > debug file contents 1`] = ` +exports[`test/lib/cli/exit-handler.js TAP handles unknown error with logs and debug file > debug file contents 1`] = ` XX timing npm:load:whichnode Completed in {TIME}ms -XX timing config:load Completed in {TIME}ms +XX silly config:load:file:{CWD}/npmrc +XX silly config:load:file:{CWD}/prefix/.npmrc +XX silly config:load:file:{CWD}/home/.npmrc +XX silly config:load:file:{CWD}/global/etc/npmrc XX timing npm:load:configload Completed in {TIME}ms XX timing npm:load:mkdirpcache Completed in {TIME}ms XX timing npm:load:mkdirplogs Completed in {TIME}ms XX verbose title npm -XX verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "notice" +XX verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" "--timing" "true" XX timing npm:load:setTitle Completed in {TIME}ms -XX timing npm:load:display Completed in {TIME}ms XX verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- XX verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log -XX timing npm:load:logFile Completed in {TIME}ms -XX timing npm:load:timers Completed in {TIME}ms -XX timing npm:load:configScope Completed in {TIME}ms XX timing npm:load Completed in {TIME}ms XX verbose stack Error: Unknown error XX verbose cwd {CWD}/prefix -XX verbose Foo 1.0.0 -XX verbose node v1.0.0 -XX verbose npm v1.0.0 +XX verbose {OS} +XX verbose {NODE-VERSION} +XX verbose npm {NPM-VERSION} XX error code ECODE XX error ERR SUMMARY Unknown error XX error ERR DETAIL Unknown error XX verbose exit 1 -XX timing npm Completed in {TIME}ms XX verbose code 1 +XX timing npm Completed in {TIME}ms +XX info timing Timing info written to: {CWD}/cache/_logs/{DATE}-timing.json XX error A complete log of this run can be found in: {CWD}/cache/_logs/{DATE}-debug-0.log ` -exports[`test/lib/utils/exit-handler.js TAP handles unknown error with logs and debug file > logs 1`] = ` +exports[`test/lib/cli/exit-handler.js TAP handles unknown error with logs and debug file > logs 1`] = ` timing npm:load:whichnode Completed in {TIME}ms -timing config:load Completed in {TIME}ms +silly config:load:file:{CWD}/npmrc +silly config:load:file:{CWD}/prefix/.npmrc +silly config:load:file:{CWD}/home/.npmrc +silly config:load:file:{CWD}/global/etc/npmrc timing npm:load:configload Completed in {TIME}ms timing npm:load:mkdirpcache Completed in {TIME}ms timing npm:load:mkdirplogs Completed in {TIME}ms verbose title npm -verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "notice" +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" "--timing" "true" timing npm:load:setTitle Completed in {TIME}ms -timing npm:load:display Completed in {TIME}ms verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log -timing npm:load:logFile Completed in {TIME}ms -timing npm:load:timers Completed in {TIME}ms -timing npm:load:configScope Completed in {TIME}ms timing npm:load Completed in {TIME}ms verbose stack Error: Unknown error verbose cwd {CWD}/prefix -verbose Foo 1.0.0 -verbose node v1.0.0 -verbose npm v1.0.0 +verbose {OS} +verbose {NODE-VERSION} +verbose npm {NPM-VERSION} error code ECODE error ERR SUMMARY Unknown error error ERR DETAIL Unknown error verbose exit 1 -timing npm Completed in {TIME}ms verbose code 1 -error A complete log of this run can be found in: {CWD}/cache/_logs/{DATE}-debug-0.log -silly logfile done cleaning log files +timing npm Completed in {TIME}ms +info timing Timing info written to: {CWD}/cache/_logs/{DATE}-timing.json +error A complete log of this run can be found in: {CWD}/cache/_logs/{DATE}-debug-0.log ` diff --git a/deps/npm/tap-snapshots/test/lib/cli/update-notifier.js.test.cjs b/deps/npm/tap-snapshots/test/lib/cli/update-notifier.js.test.cjs new file mode 100644 index 00000000000000..244d5216340f80 --- /dev/null +++ b/deps/npm/tap-snapshots/test/lib/cli/update-notifier.js.test.cjs @@ -0,0 +1,102 @@ +/* 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/cli/update-notifier.js TAP notification situations 122.420.69 - color=always > must match snapshot 1`] = ` + +New major version of npm available! 122.420.69 -> 123.420.69 +Changelog: https://github.com/npm/cli/releases/tag/v123.420.69 +To update run: npm install -g npm@123.420.69 + +` + +exports[`test/lib/cli/update-notifier.js TAP notification situations 122.420.69 - color=false > must match snapshot 1`] = ` + +New major version of npm available! 122.420.69 -> 123.420.69 +Changelog: https://github.com/npm/cli/releases/tag/v123.420.69 +To update run: npm install -g npm@123.420.69 + +` + +exports[`test/lib/cli/update-notifier.js TAP notification situations 123.419.69 - color=always > must match snapshot 1`] = ` + +New minor version of npm available! 123.419.69 -> 123.420.69 +Changelog: https://github.com/npm/cli/releases/tag/v123.420.69 +To update run: npm install -g npm@123.420.69 + +` + +exports[`test/lib/cli/update-notifier.js TAP notification situations 123.419.69 - color=false > must match snapshot 1`] = ` + +New minor version of npm available! 123.419.69 -> 123.420.69 +Changelog: https://github.com/npm/cli/releases/tag/v123.420.69 +To update run: npm install -g npm@123.420.69 + +` + +exports[`test/lib/cli/update-notifier.js TAP notification situations 123.420.68 - color=always > must match snapshot 1`] = ` + +New patch version of npm available! 123.420.68 -> 123.420.69 +Changelog: https://github.com/npm/cli/releases/tag/v123.420.69 +To update run: npm install -g npm@123.420.69 + +` + +exports[`test/lib/cli/update-notifier.js TAP notification situations 123.420.68 - color=false > must match snapshot 1`] = ` + +New patch version of npm available! 123.420.68 -> 123.420.69 +Changelog: https://github.com/npm/cli/releases/tag/v123.420.69 +To update run: npm install -g npm@123.420.69 + +` + +exports[`test/lib/cli/update-notifier.js TAP notification situations 123.420.70 - color=always > must match snapshot 1`] = ` + +New minor version of npm available! 123.420.70 -> 123.421.70 +Changelog: https://github.com/npm/cli/releases/tag/v123.421.70 +To update run: npm install -g npm@123.421.70 + +` + +exports[`test/lib/cli/update-notifier.js TAP notification situations 123.420.70 - color=false > must match snapshot 1`] = ` + +New minor version of npm available! 123.420.70 -> 123.421.70 +Changelog: https://github.com/npm/cli/releases/tag/v123.421.70 +To update run: npm install -g npm@123.421.70 + +` + +exports[`test/lib/cli/update-notifier.js TAP notification situations 123.421.69 - color=always > must match snapshot 1`] = ` + +New patch version of npm available! 123.421.69 -> 123.421.70 +Changelog: https://github.com/npm/cli/releases/tag/v123.421.70 +To update run: npm install -g npm@123.421.70 + +` + +exports[`test/lib/cli/update-notifier.js TAP notification situations 123.421.69 - color=false > must match snapshot 1`] = ` + +New patch version of npm available! 123.421.69 -> 123.421.70 +Changelog: https://github.com/npm/cli/releases/tag/v123.421.70 +To update run: npm install -g npm@123.421.70 + +` + +exports[`test/lib/cli/update-notifier.js TAP notification situations 124.0.0-beta.0 - color=always > must match snapshot 1`] = ` + +New prerelease version of npm available! 124.0.0-beta.0 -> 124.0.0-beta.99999 +Changelog: https://github.com/npm/cli/releases/tag/v124.0.0-beta.99999 +To update run: npm install -g npm@124.0.0-beta.99999 + +` + +exports[`test/lib/cli/update-notifier.js TAP notification situations 124.0.0-beta.0 - color=false > must match snapshot 1`] = ` + +New prerelease version of npm available! 124.0.0-beta.0 -> 124.0.0-beta.99999 +Changelog: https://github.com/npm/cli/releases/tag/v124.0.0-beta.99999 +To update run: npm install -g npm@124.0.0-beta.99999 + +` diff --git a/deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs index 7611191688268c..21c22b26c12e6b 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs @@ -45,7 +45,6 @@ exports[`test/lib/commands/audit.js TAP audit signatures ignores optional depend audited 1 package in xxx 1 package has a verified registry signature - ` exports[`test/lib/commands/audit.js TAP audit signatures json output with invalid and missing signatures > must match snapshot 1`] = ` @@ -131,14 +130,12 @@ exports[`test/lib/commands/audit.js TAP audit signatures multiple registries wit audited 2 packages in xxx 2 packages have verified registry signatures - ` exports[`test/lib/commands/audit.js TAP audit signatures omit dev dependencies with missing signature > must match snapshot 1`] = ` audited 1 package in xxx 1 package has a verified registry signature - ` exports[`test/lib/commands/audit.js TAP audit signatures output details about missing signatures > must match snapshot 1`] = ` @@ -157,7 +154,6 @@ audited 1 package in xxx @npmcli/arborist@1.0.14 (https://verdaccio-clone.org/) Someone might have tampered with this package since it was published on the registry! - ` exports[`test/lib/commands/audit.js TAP audit signatures third-party registry with keys and missing signatures errors > must match snapshot 1`] = ` @@ -172,21 +168,18 @@ exports[`test/lib/commands/audit.js TAP audit signatures third-party registry wi audited 1 package in xxx 1 package has a verified registry signature - ` exports[`test/lib/commands/audit.js TAP audit signatures third-party registry with sub-path (trailing slash) > must match snapshot 1`] = ` audited 1 package in xxx 1 package has a verified registry signature - ` exports[`test/lib/commands/audit.js TAP audit signatures third-party registry with sub-path > must match snapshot 1`] = ` audited 1 package in xxx 1 package has a verified registry signature - ` exports[`test/lib/commands/audit.js TAP audit signatures with both invalid and missing signatures > must match snapshot 1`] = ` @@ -201,14 +194,12 @@ async@1.1.1 (https://registry.npmjs.org/) kms-demo@1.0.0 (https://registry.npmjs.org/) Someone might have tampered with this package since it was published on the registry! - ` exports[`test/lib/commands/audit.js TAP audit signatures with bundled and peer deps and no signatures > must match snapshot 1`] = ` audited 1 package in xxx 1 package has a verified registry signature - ` exports[`test/lib/commands/audit.js TAP audit signatures with invalid attestations > must match snapshot 1`] = ` @@ -219,7 +210,6 @@ audited 1 package in xxx sigstore@1.0.0 (https://registry.npmjs.org/) Someone might have tampered with this package since it was published on the registry! - ` exports[`test/lib/commands/audit.js TAP audit signatures with invalid signatures > must match snapshot 1`] = ` @@ -230,25 +220,22 @@ audited 1 package in xxx kms-demo@1.0.0 (https://registry.npmjs.org/) Someone might have tampered with this package since it was published on the registry! - ` -exports[`test/lib/commands/audit.js TAP audit signatures with invalid signtaures and color output enabled > must match snapshot 1`] = ` +exports[`test/lib/commands/audit.js TAP audit signatures with invalid signatures and color output enabled > must match snapshot 1`] = ` audited 1 package in xxx -1 package has an invalid registry signature: +1 package has an invalid registry signature: kms-demo@1.0.0 (https://registry.npmjs.org/) Someone might have tampered with this package since it was published on the registry! - ` exports[`test/lib/commands/audit.js TAP audit signatures with key fallback to legacy API > must match snapshot 1`] = ` audited 1 package in xxx 1 package has a verified registry signature - ` exports[`test/lib/commands/audit.js TAP audit signatures with keys but missing signature > must match snapshot 1`] = ` @@ -268,7 +255,6 @@ sigstore@1.0.0 (https://registry.npmjs.org/) tuf-js@1.0.0 (https://registry.npmjs.org/) Someone might have tampered with these packages since they were published on the registry! - ` exports[`test/lib/commands/audit.js TAP audit signatures with multiple invalid signatures > must match snapshot 1`] = ` @@ -280,7 +266,6 @@ async@1.1.1 (https://registry.npmjs.org/) kms-demo@1.0.0 (https://registry.npmjs.org/) Someone might have tampered with these packages since they were published on the registry! - ` exports[`test/lib/commands/audit.js TAP audit signatures with multiple missing signatures > must match snapshot 1`] = ` @@ -302,7 +287,6 @@ audited 3 packages in xxx node-fetch@1.6.0 (https://registry.npmjs.org/) Someone might have tampered with this package since it was published on the registry! - ` exports[`test/lib/commands/audit.js TAP audit signatures with valid and missing signatures > must match snapshot 1`] = ` @@ -321,35 +305,30 @@ audited 1 package in xxx 1 package has a verified registry signature 1 package has a verified attestation - ` exports[`test/lib/commands/audit.js TAP audit signatures with valid signatures > must match snapshot 1`] = ` audited 1 package in xxx 1 package has a verified registry signature - ` exports[`test/lib/commands/audit.js TAP audit signatures with valid signatures using alias > must match snapshot 1`] = ` audited 1 package in xxx 1 package has a verified registry signature - ` exports[`test/lib/commands/audit.js TAP audit signatures workspaces verifies registry deps and ignores local workspace deps > must match snapshot 1`] = ` audited 3 packages in xxx 3 packages have verified registry signatures - ` exports[`test/lib/commands/audit.js TAP audit signatures workspaces verifies registry deps when filtering by workspace name > must match snapshot 1`] = ` audited 2 packages in xxx 2 packages have verified registry signatures - ` exports[`test/lib/commands/audit.js TAP fallback audit > must match snapshot 1`] = ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/completion.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/completion.js.test.cjs index 089d92440f653f..a538e3c0688633 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/completion.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/completion.js.test.cjs @@ -7,12 +7,10 @@ 'use strict' exports[`test/lib/commands/completion.js TAP completion --no- flags > flags 1`] = ` Array [ - Array [ - String( - --no-version - --no-versions - ), - ], + String( + --no-version + --no-versions + ), ] ` @@ -42,133 +40,131 @@ Array [] exports[`test/lib/commands/completion.js TAP completion double dashes escape from flag completion > full command list 1`] = ` Array [ - Array [ - String( - access - adduser - audit - bugs - cache - ci - completion - config - dedupe - deprecate - diff - dist-tag - docs - doctor - edit - exec - explain - explore - find-dupes - fund - get - help - help-search - hook - init - install - install-ci-test - install-test - link - ll - login - logout - ls - org - outdated - owner - pack - ping - pkg - prefix - profile - prune - publish - query - rebuild - repo - restart - root - run-script - sbom - search - set - shrinkwrap - star - stars - start - stop - team - test - token - uninstall - unpublish - unstar - update - version - view - whoami - author - home - issues - info - show - find - add - unlink - remove - rm - r - un - rb - list - ln - create - i - it - cit - up - c - s - se - tst - t - ddp - v - run - clean-install - clean-install-test - x - why - la - verison - ic - innit - in - ins - inst - insta - instal - isnt - isnta - isntal - isntall - install-clean - isntall-clean - hlep - dist-tags - upgrade - udpate - rum - sit - urn - ogr - add-user - ), - ], + String( + access + adduser + audit + bugs + cache + ci + completion + config + dedupe + deprecate + diff + dist-tag + docs + doctor + edit + exec + explain + explore + find-dupes + fund + get + help + help-search + hook + init + install + install-ci-test + install-test + link + ll + login + logout + ls + org + outdated + owner + pack + ping + pkg + prefix + profile + prune + publish + query + rebuild + repo + restart + root + run-script + sbom + search + set + shrinkwrap + star + stars + start + stop + team + test + token + uninstall + unpublish + unstar + update + version + view + whoami + author + home + issues + info + show + find + add + unlink + remove + rm + r + un + rb + list + ln + create + i + it + cit + up + c + s + se + tst + t + ddp + v + run + clean-install + clean-install-test + x + why + la + verison + ic + innit + in + ins + inst + insta + instal + isnt + isnta + isntal + isntall + install-clean + isntall-clean + hlep + dist-tags + upgrade + udpate + rum + sit + urn + ogr + add-user + ), ] ` @@ -178,52 +174,44 @@ Array [] exports[`test/lib/commands/completion.js TAP completion flags > flags 1`] = ` Array [ - Array [ - String( - --version - --versions - --viewer - --verbose - --v - ), - ], + String( + --version + --versions + --viewer + --verbose + --v + ), ] ` exports[`test/lib/commands/completion.js TAP completion multiple command names > multiple command names 1`] = ` Array [ - Array [ - String( - access - adduser - audit - author - add - add-user - ), - ], + String( + access + adduser + audit + author + add + add-user + ), ] ` exports[`test/lib/commands/completion.js TAP completion single command name > single command name 1`] = ` Array [ - Array [ - "config", - ], + "config", ] ` exports[`test/lib/commands/completion.js TAP completion subcommand completion > subcommands 1`] = ` Array [ - Array [ - String( - get - grant - list - revoke - set - ), - ], + String( + get + grant + list + revoke + set + ), ] ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs index 9d67091f7a0d4e..c018a356f7d21c 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs @@ -7,9 +7,7 @@ 'use strict' exports[`test/lib/commands/config.js TAP config list --json > output matches snapshot 1`] = ` { - "prefix": "{LOCALPREFIX}", - "userconfig": "{HOME}/.npmrc", - "cache": "{NPMDIR}/test/lib/commands/tap-testdir-config-config-list---json-sandbox/cache", + "cache": "{CACHE}", "json": true, "projectloaded": "yes", "userloaded": "yes", @@ -31,7 +29,7 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "call": "", "cert": null, "cidr": null, - "color": true, + "color": {COLOR}, "commit-hooks": true, "cpu": null, "depth": null, @@ -62,7 +60,7 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "git": "git", "git-tag-version": true, "global": false, - "globalconfig": "{GLOBALPREFIX}/npmrc", + "globalconfig": "{CWD}/global/etc/npmrc", "global-style": false, "heading": "npm", "https-proxy": null, @@ -75,13 +73,13 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "init-author-name": "", "init-author-url": "", "init-license": "ISC", - "init-module": "{HOME}/.npm-init.js", + "init-module": "{CWD}/home/.npm-init.js", "init-version": "1.0.0", "init.author.email": "", "init.author.name": "", "init.author.url": "", "init.license": "ISC", - "init.module": "{HOME}/.npm-init.js", + "init.module": "{CWD}/home/.npm-init.js", "init.version": "1.0.0", "install-links": false, "install-strategy": "hoisted", @@ -118,9 +116,10 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "prefer-dedupe": false, "prefer-offline": false, "prefer-online": false, + "prefix": "{CWD}/global", "preid": "", "production": null, - "progress": true, + "progress": {PROGRESS}, "provenance": false, "provenance-file": null, "proxy": null, @@ -158,6 +157,7 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "update-notifier": true, "usage": false, "user-agent": "npm/{npm-version} node/{node-version} {platform} {arch} workspaces/{workspaces} {ci}", + "userconfig": "{CWD}/home/.npmrc", "version": false, "versions": false, "viewer": "{VIEWER}", @@ -192,7 +192,7 @@ cafile = null call = "" cert = null cidr = null -color = true +color = {COLOR} commit-hooks = true cpu = null depth = null @@ -224,7 +224,7 @@ git = "git" git-tag-version = true global = false global-style = false -globalconfig = "{GLOBALPREFIX}/npmrc" +globalconfig = "{CWD}/global/etc/npmrc" heading = "npm" https-proxy = null if-present = false @@ -236,13 +236,13 @@ init-author-email = "" init-author-name = "" init-author-url = "" init-license = "ISC" -init-module = "{HOME}/.npm-init.js" +init-module = "{CWD}/home/.npm-init.js" init-version = "1.0.0" init.author.email = "" init.author.name = "" init.author.url = "" init.license = "ISC" -init.module = "{HOME}/.npm-init.js" +init.module = "{CWD}/home/.npm-init.js" init.version = "1.0.0" install-links = false install-strategy = "hoisted" @@ -279,10 +279,10 @@ parseable = false prefer-dedupe = false prefer-offline = false prefer-online = false -; prefix = "{REALGLOBALREFIX}" ; overridden by cli +prefix = "{CWD}/global" preid = "" production = null -progress = true +progress = {PROGRESS} provenance = false provenance-file = null proxy = null @@ -320,7 +320,7 @@ unicode = false update-notifier = true usage = false user-agent = "npm/{npm-version} node/{node-version} {platform} {arch} workspaces/{workspaces} {ci}" -; userconfig = "{HOME}/.npmrc" ; overridden by cli +userconfig = "{CWD}/home/.npmrc" version = false versions = false viewer = "{VIEWER}" @@ -330,98 +330,81 @@ workspaces = null workspaces-update = true yes = null -; "global" config from {GLOBALPREFIX}/npmrc +; "global" config from {CWD}/global/etc/npmrc globalloaded = "yes" -; "user" config from {HOME}/.npmrc +; "user" config from {CWD}/home/.npmrc userloaded = "yes" -; "project" config from {LOCALPREFIX}/.npmrc +; "project" config from {CWD}/prefix/.npmrc projectloaded = "yes" ; "cli" config from command line options -cache = "{NPMDIR}/test/lib/commands/tap-testdir-config-config-list---long-sandbox/cache" +cache = "{CACHE}" long = true -prefix = "{LOCALPREFIX}" -userconfig = "{HOME}/.npmrc" ` exports[`test/lib/commands/config.js TAP config list > output matches snapshot 1`] = ` -; "global" config from {GLOBALPREFIX}/npmrc +; "global" config from {CWD}/global/etc/npmrc globalloaded = "yes" -; "user" config from {HOME}/.npmrc +; "user" config from {CWD}/home/.npmrc userloaded = "yes" -; "project" config from {LOCALPREFIX}/.npmrc +; "project" config from {CWD}/prefix/.npmrc projectloaded = "yes" ; "cli" config from command line options -cache = "{NPMDIR}/test/lib/commands/tap-testdir-config-config-list-sandbox/cache" -prefix = "{LOCALPREFIX}" -userconfig = "{HOME}/.npmrc" +cache = "{CACHE}" -; node bin location = {EXECPATH} +; node bin location = {NODE-BIN-LOCATION} ; node version = {NODE-VERSION} -; npm local prefix = {LOCALPREFIX} +; npm local prefix = {CWD}/prefix ; npm version = {NPM-VERSION} -; cwd = {NPMDIR} -; HOME = {HOME} +; cwd = {CWD}/prefix +; HOME = {CWD}/home ; Run \`npm config ls -l\` to show all defaults. ` -exports[`test/lib/commands/config.js TAP config list with publishConfig > output matches snapshot 1`] = ` +exports[`test/lib/commands/config.js TAP config list with publishConfig global > output matches snapshot 1`] = ` ; "cli" config from command line options -cache = "{NPMDIR}/test/lib/commands/tap-testdir-config-config-list-with-publishConfig-sandbox/cache" -prefix = "{LOCALPREFIX}" -userconfig = "{HOME}/.npmrc" +cache = "{CACHE}" +global = true -; node bin location = {EXECPATH} +; node bin location = {NODE-BIN-LOCATION} ; node version = {NODE-VERSION} -; npm local prefix = {LOCALPREFIX} +; npm local prefix = {CWD}/prefix ; npm version = {NPM-VERSION} -; cwd = {NPMDIR} -; HOME = {HOME} +; cwd = {CWD}/prefix +; HOME = {CWD}/home ; Run \`npm config ls -l\` to show all defaults. +` -; "publishConfig" from {LOCALPREFIX}/package.json -; This set of config values will be used at publish-time. - -_authToken = (protected) -registry = "https://some.registry" -; "env" config from environment - -; cache = "{NPMDIR}/test/lib/commands/tap-testdir-config-config-list-with-publishConfig-sandbox/cache" ; overridden by cli -global-prefix = "{LOCALPREFIX}" -globalconfig = "{GLOBALPREFIX}/npmrc" -init-module = "{HOME}/.npm-init.js" -local-prefix = "{LOCALPREFIX}" -npm-version = "{NPM-VERSION}" -; prefix = "{LOCALPREFIX}" ; overridden by cli -user-agent = "npm/{NPM-VERSION} node/{NODE-VERSION} {PLATFORM} {ARCH} workspaces/false" -; userconfig = "{HOME}/.npmrc" ; overridden by cli - +exports[`test/lib/commands/config.js TAP config list with publishConfig local > output matches snapshot 1`] = ` ; "cli" config from command line options -cache = "{NPMDIR}/test/lib/commands/tap-testdir-config-config-list-with-publishConfig-sandbox/cache" -global = true -prefix = "{LOCALPREFIX}" -userconfig = "{HOME}/.npmrc" +cache = "{CACHE}" -; node bin location = {EXECPATH} +; node bin location = {NODE-BIN-LOCATION} ; node version = {NODE-VERSION} -; npm local prefix = {LOCALPREFIX} +; npm local prefix = {CWD}/prefix ; npm version = {NPM-VERSION} -; cwd = {NPMDIR} -; HOME = {HOME} +; cwd = {CWD}/prefix +; HOME = {CWD}/home ; Run \`npm config ls -l\` to show all defaults. + +; "publishConfig" from {CWD}/prefix/package.json +; This set of config values will be used at publish-time. + +_authToken = (protected) +registry = "https://some.registry" ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs index ebc823e7e06bbd..854f93ff1e5f2c 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs @@ -20,7 +20,22 @@ latest: 1.0.0 ` exports[`test/lib/commands/dist-tag.js TAP ls on missing package > should log no dist-tag found msg 1`] = ` -dist-tag ls Couldn't get dist-tag data for foo@* +dist-tag ls Couldn't get dist-tag data for Result { +dist-tag ls type: 'range', +dist-tag ls registry: true, +dist-tag ls where: undefined, +dist-tag ls raw: 'foo', +dist-tag ls name: 'foo', +dist-tag ls escapedName: 'foo', +dist-tag ls scope: undefined, +dist-tag ls rawSpec: '*', +dist-tag ls saveSpec: null, +dist-tag ls fetchSpec: '*', +dist-tag ls gitRange: undefined, +dist-tag ls gitCommittish: undefined, +dist-tag ls gitSubdir: undefined, +dist-tag ls hosted: undefined +dist-tag ls } ` exports[`test/lib/commands/dist-tag.js TAP ls on named package > should list tags for the specified package 1`] = ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs index 98d10c2bb5d4bb..0481c6d86823e8 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs @@ -9,123 +9,111 @@ exports[`test/lib/commands/doctor.js TAP all clear > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP all clear > output 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP all clear in color > everything is ok in color 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP all clear in color > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "/u001b[94mdoctor/u001b[39m Running checkup", + "/u001b[94mdoctor/u001b[39m Pinging registry", + "/u001b[94mdoctor/u001b[39m Getting npm package information", + "/u001b[94mdoctor/u001b[39m Getting Node.js release information", + "/u001b[94mdoctor/u001b[39m Finding git in your PATH", + "/u001b[94mdoctor/u001b[39m getBinPath Finding npm global bin in your PATH", + "/u001b[94mdoctor/u001b[39m verifyCachedFiles Verifying the npm cache", + String( + /u001b[94mdoctor/u001b[39m verifyCachedFiles Verification complete. Stats: { + /u001b[94mdoctor/u001b[39m "badContentCount": 0, + /u001b[94mdoctor/u001b[39m "reclaimedCount": 0, + /u001b[94mdoctor/u001b[39m "missingContent": 0, + /u001b[94mdoctor/u001b[39m "verifiedContent": 0 + /u001b[94mdoctor/u001b[39m } + ), ], "warn": Array [], } @@ -135,133 +123,116 @@ exports[`test/lib/commands/doctor.js TAP bad proxy > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP bad proxy > output 1`] = ` -Check Value Recommendation/Notes -npm ping not ok Invalid protocol \`ssh:\` connecting to proxy \`npmjs.org\` -npm -v not ok Error: Invalid protocol \`ssh:\` connecting to proxy \`npmjs.org\` -node -v not ok Error: Invalid protocol \`ssh:\` connecting to proxy \`npmjs.org\` -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Not ok +Invalid protocol \`ssh:\` connecting to proxy \`npmjs.org\` +Checking npm version +Not ok +Error: Invalid protocol \`ssh:\` connecting to proxy \`npmjs.org\` +Checking node version +Not ok +Error: Invalid protocol \`ssh:\` connecting to proxy \`npmjs.org\` +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP cacache badContent > corrupted cache content 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 2 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 2 tarballs ` exports[`test/lib/commands/doctor.js TAP cacache badContent > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 1, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 2 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 1, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 2 + doctor } + ), ], "warn": Array [ - Array [ - "verifyCachedFiles", - "Corrupted content removed: 1", - ], - Array [ - "verifyCachedFiles", - "Cache issues have been fixed", - ], + "doctor verifyCachedFiles Corrupted content removed: 1", + "doctor verifyCachedFiles Cache issues have been fixed", ], } ` @@ -270,142 +241,118 @@ exports[`test/lib/commands/doctor.js TAP cacache missingContent > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 1, - "verifiedContent": 2 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 1, + doctor "verifiedContent": 2 + doctor } + ), ], "warn": Array [ - Array [ - "verifyCachedFiles", - "Missing content: 1", - ], - Array [ - "verifyCachedFiles", - "Cache issues have been fixed", - ], + "doctor verifyCachedFiles Missing content: 1", + "doctor verifyCachedFiles Cache issues have been fixed", ], } ` exports[`test/lib/commands/doctor.js TAP cacache missingContent > missing content 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 2 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 2 tarballs ` exports[`test/lib/commands/doctor.js TAP cacache reclaimedCount > content garbage collected 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 2 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 2 tarballs ` exports[`test/lib/commands/doctor.js TAP cacache reclaimedCount > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 1, - "missingContent": 0, - "verifiedContent": 2 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 1, + doctor "missingContent": 0, + doctor "verifiedContent": 2 + doctor } + ), ], "warn": Array [ - Array [ - "verifyCachedFiles", - "Content garbage-collected: 1 (undefined bytes)", - ], - Array [ - "verifyCachedFiles", - "Cache issues have been fixed", - ], + "doctor verifyCachedFiles Content garbage-collected: 1 (undefined bytes)", + "doctor verifyCachedFiles Cache issues have been fixed", ], } ` @@ -414,414 +361,348 @@ exports[`test/lib/commands/doctor.js TAP discrete checks cache > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP discrete checks cache > output 1`] = ` -Check Value Recommendation/Notes -Perms check on cached files ok -Verify cache contents ok verified 0 tarballs +Checking permissions on cached files (this may take awhile) +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP discrete checks git > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], + "doctor Running checkup", ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP discrete checks git > output 1`] = ` -Check Value Recommendation/Notes + ` exports[`test/lib/commands/doctor.js TAP discrete checks invalid environment > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], + "doctor Running checkup", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP discrete checks invalid environment > output 1`] = ` -Check Value Recommendation/Notes -git executable in PATH ok /path/to/git -global bin folder in PATH not ok Error: Add {CWD}/global/bin to your $PATH +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Not ok +Error: Add {CWD}/global/bin to your $PATH ` exports[`test/lib/commands/doctor.js TAP discrete checks permissions - not windows > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], + "doctor Running checkup", ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP discrete checks permissions - not windows > output 1`] = ` -Check Value Recommendation/Notes -Perms check on cached files ok -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 +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok ` exports[`test/lib/commands/doctor.js TAP discrete checks permissions - windows > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], + "doctor Running checkup", ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP discrete checks permissions - windows > output 1`] = ` -Check Value Recommendation/Notes + ` exports[`test/lib/commands/doctor.js TAP discrete checks ping > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], + "doctor Running checkup", + "doctor Pinging registry", ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP discrete checks ping > output 1`] = ` -Check Value Recommendation/Notes -npm ping ok +Connecting to the registry +Ok ` exports[`test/lib/commands/doctor.js TAP discrete checks registry > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], + "doctor Running checkup", + "doctor Pinging registry", ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP discrete checks registry > output 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm config get registry ok using default registry (https://registry.npmjs.org/) +Connecting to the registry +Ok +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) ` exports[`test/lib/commands/doctor.js TAP discrete checks versions > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], + "doctor Running checkup", + "doctor Getting npm package information", + "doctor Getting Node.js release information", ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP discrete checks versions > output 1`] = ` -Check Value Recommendation/Notes -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 ` exports[`test/lib/commands/doctor.js TAP error reading directory > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [ - Array [ - "checkFilesPermission", - "error reading directory {CWD}/cache", - ], - Array [ - "checkFilesPermission", - "error reading directory {CWD}/prefix/node_modules", - ], - Array [ - "checkFilesPermission", - "error reading directory {CWD}/global/node_modules", - ], - Array [ - "checkFilesPermission", - "error reading directory {CWD}/prefix/node_modules/.bin", - ], - Array [ - "checkFilesPermission", - "error reading directory {CWD}/global/bin", - ], + "doctor checkFilesPermission error reading directory {CWD}/cache", + "doctor checkFilesPermission error reading directory {CWD}/prefix/node_modules", + "doctor checkFilesPermission error reading directory {CWD}/global/node_modules", + "doctor checkFilesPermission error reading directory {CWD}/prefix/node_modules/.bin", + "doctor checkFilesPermission error reading directory {CWD}/global/bin", ], } ` exports[`test/lib/commands/doctor.js TAP error reading directory > readdir error 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files not ok Check the permissions of files in {CWD}/cache (should be owned by current user) -Perms check on local node_modules not ok Check the permissions of files in {CWD}/prefix/node_modules (should be owned by current user) -Perms check on global node_modules not ok Check the permissions of files in {CWD}/global/node_modules -Perms check on local bin folder not ok Check the permissions of files in {CWD}/prefix/node_modules/.bin -Perms check on global bin folder not ok Check the permissions of files in {CWD}/global/bin -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Not ok +Check the permissions of files in {CWD}/cache (should be owned by current user) +Checking permissions on local node_modules (this may take awhile) +Not ok +Check the permissions of files in {CWD}/prefix/node_modules (should be owned by current user) +Checking permissions on global node_modules (this may take awhile) +Not ok +Check the permissions of files in {CWD}/global/node_modules +Checking permissions on local bin folder +Not ok +Check the permissions of files in {CWD}/prefix/node_modules/.bin +Checking permissions on global bin folder +Not ok +Check the permissions of files in {CWD}/global/bin +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP incorrect owner > incorrect owner 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files not ok Check the permissions of files in {CWD}/cache (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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Not ok +Check the permissions of files in {CWD}/cache (should be owned by current user) +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP incorrect owner > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [ - Array [ - "checkFilesPermission", - "should be owner of {CWD}/cache/_cacache", - ], + "doctor checkFilesPermission should be owner of {CWD}/cache/_cacache", ], } ` exports[`test/lib/commands/doctor.js TAP incorrect permissions > incorrect owner 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files not ok Check the permissions of files in {CWD}/cache (should be owned by current user) -Perms check on local node_modules not ok Check the permissions of files in {CWD}/prefix/node_modules (should be owned by current user) -Perms check on global node_modules not ok Check the permissions of files in {CWD}/global/node_modules -Perms check on local bin folder not ok Check the permissions of files in {CWD}/prefix/node_modules/.bin -Perms check on global bin folder not ok Check the permissions of files in {CWD}/global/bin -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Not ok +Check the permissions of files in {CWD}/cache (should be owned by current user) +Checking permissions on local node_modules (this may take awhile) +Not ok +Check the permissions of files in {CWD}/prefix/node_modules (should be owned by current user) +Checking permissions on global node_modules (this may take awhile) +Not ok +Check the permissions of files in {CWD}/global/node_modules +Checking permissions on local bin folder +Not ok +Check the permissions of files in {CWD}/prefix/node_modules/.bin +Checking permissions on global bin folder +Not ok +Check the permissions of files in {CWD}/global/bin +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP incorrect permissions > logs 1`] = ` Object { "error": Array [ - Array [ - "checkFilesPermission", - "Missing permissions on {CWD}/cache (expect: readable)", - ], - Array [ - "checkFilesPermission", - "Missing permissions on {CWD}/prefix/node_modules (expect: readable, writable)", - ], - Array [ - "checkFilesPermission", - "Missing permissions on {CWD}/global/node_modules (expect: readable)", - ], - Array [ - "checkFilesPermission", - "Missing permissions on {CWD}/prefix/node_modules/.bin (expect: readable, writable, executable)", - ], - Array [ - "checkFilesPermission", - "Missing permissions on {CWD}/global/bin (expect: executable)", - ], + "doctor checkFilesPermission Missing permissions on {CWD}/cache (expect: readable)", + "doctor checkFilesPermission Missing permissions on {CWD}/prefix/node_modules (expect: readable, writable)", + "doctor checkFilesPermission Missing permissions on {CWD}/global/node_modules (expect: readable)", + "doctor checkFilesPermission Missing permissions on {CWD}/prefix/node_modules/.bin (expect: readable, writable, executable)", + "doctor checkFilesPermission Missing permissions on {CWD}/global/bin (expect: executable)", ], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [], } @@ -831,720 +712,651 @@ exports[`test/lib/commands/doctor.js TAP missing git > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [ - Array [ - Error: test error, - ], + String( + doctor getGitPath Error: test error + doctor at {STACK} + doctor at {STACK} + doctor at {STACK} + doctor at {STACK} + doctor at {STACK} + ), ], } ` exports[`test/lib/commands/doctor.js TAP missing git > missing git 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH not ok Error: Install git and ensure it's in your PATH. -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Not ok +Error: Install git and ensure it's in your PATH. +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP missing global directories > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [ - Array [ - "checkFilesPermission", - "error getting info for {CWD}/global/node_modules", - ], - Array [ - "checkFilesPermission", - "error getting info for {CWD}/global/bin", - ], + "doctor checkFilesPermission error getting info for {CWD}/global/node_modules", + "doctor checkFilesPermission error getting info for {CWD}/global/bin", ], } ` exports[`test/lib/commands/doctor.js TAP missing global directories > missing global directories 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -Perms check on local node_modules ok -Perms check on global node_modules not ok Check the permissions of files in {CWD}/global/node_modules -Perms check on local bin folder ok -Perms check on global bin folder not ok Check the permissions of files in {CWD}/global/bin -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Not ok +Check the permissions of files in {CWD}/global/node_modules +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Not ok +Check the permissions of files in {CWD}/global/bin +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP missing local node_modules > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP missing local node_modules > missing local node_modules 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP node out of date - current > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP node out of date - current > node is out of date 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v not ok Use node v2.0.1 (current: v2.0.0) -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Not ok +Use node v2.0.1 (current: v2.0.0) +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP node out of date - lts > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP node out of date - lts > node is out of date 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v not ok Use node v1.0.0 (current: v0.0.1) -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Not ok +Use node v1.0.0 (current: v0.0.1) +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP non-default registry > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP non-default registry > non default registry 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry not ok Try \`npm config set registry=https://registry.npmjs.org/\` -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Not ok +Try \`npm config set registry=https://registry.npmjs.org/\` +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP npm out of date > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP npm out of date > npm is out of date 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v not ok Use npm v2.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Ok +Checking npm version +Not ok +Use npm v2.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP ping 404 > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP ping 404 > ping 404 1`] = ` -Check Value Recommendation/Notes -npm ping not ok 404 404 Not Found - GET https://registry.npmjs.org/-/ping?write=true -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Not ok +404 404 Not Found - GET https://registry.npmjs.org/-/ping?write=true +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP ping 404 in color > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "/u001b[94mdoctor/u001b[39m Running checkup", + "/u001b[94mdoctor/u001b[39m Pinging registry", + "/u001b[94mdoctor/u001b[39m Getting npm package information", + "/u001b[94mdoctor/u001b[39m Getting Node.js release information", + "/u001b[94mdoctor/u001b[39m Finding git in your PATH", + "/u001b[94mdoctor/u001b[39m getBinPath Finding npm global bin in your PATH", + "/u001b[94mdoctor/u001b[39m verifyCachedFiles Verifying the npm cache", + String( + /u001b[94mdoctor/u001b[39m verifyCachedFiles Verification complete. Stats: { + /u001b[94mdoctor/u001b[39m "badContentCount": 0, + /u001b[94mdoctor/u001b[39m "reclaimedCount": 0, + /u001b[94mdoctor/u001b[39m "missingContent": 0, + /u001b[94mdoctor/u001b[39m "verifiedContent": 0 + /u001b[94mdoctor/u001b[39m } + ), ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP ping 404 in color > ping 404 in color 1`] = ` -Check Value Recommendation/Notes -npm ping not ok 404 404 Not Found - GET https://registry.npmjs.org/-/ping?write=true -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Not ok +404 404 Not Found - GET https://registry.npmjs.org/-/ping?write=true +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP ping exception with code > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP ping exception with code > ping failure 1`] = ` -Check Value Recommendation/Notes -npm ping not ok request to https://registry.npmjs.org/-/ping?write=true failed, reason: Test Error -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Not ok +request to https://registry.npmjs.org/-/ping?write=true failed, reason: Test Error +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP ping exception without code > logs 1`] = ` Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", + "doctor verifyCachedFiles Verifying the npm cache", + String( + doctor verifyCachedFiles Verification complete. Stats: { + doctor "badContentCount": 0, + doctor "reclaimedCount": 0, + doctor "missingContent": 0, + doctor "verifiedContent": 0 + doctor } + ), ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP ping exception without code > ping failure 1`] = ` -Check Value Recommendation/Notes -npm ping not ok request to https://registry.npmjs.org/-/ping?write=true failed, reason: Test Error -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global/bin -Perms check on cached files ok -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 -Verify cache contents ok verified 0 tarballs +Connecting to the registry +Not ok +request to https://registry.npmjs.org/-/ping?write=true failed, reason: Test Error +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global/bin +Checking permissions on cached files (this may take awhile) +Ok +Checking permissions on local node_modules (this may take awhile) +Ok +Checking permissions on global node_modules (this may take awhile) +Ok +Checking permissions on local bin folder +Ok +Checking permissions on global bin folder +Ok +Verifying cache contents (this may take awhile) +Ok +verified 0 tarballs ` exports[`test/lib/commands/doctor.js TAP silent errors > logs 1`] = ` Object { "error": Array [], - "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - ], + "info": Array [], "warn": Array [], } ` @@ -1556,46 +1368,7 @@ exports[`test/lib/commands/doctor.js TAP silent errors > output 1`] = ` exports[`test/lib/commands/doctor.js TAP silent success > logs 1`] = ` Object { "error": Array [], - "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], - Array [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], - ], + "info": Array [], "warn": Array [], } ` @@ -1608,40 +1381,33 @@ exports[`test/lib/commands/doctor.js TAP windows skips permissions checks > logs Object { "error": Array [], "info": Array [ - Array [ - "Running checkup", - ], - Array [ - "checkPing", - "Pinging registry", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git in your PATH", - ], - Array [ - "getBinPath", - "Finding npm global bin in your PATH", - ], + "doctor Running checkup", + "doctor Pinging registry", + "doctor Getting npm package information", + "doctor Getting Node.js release information", + "doctor Finding git in your PATH", + "doctor getBinPath Finding npm global bin in your PATH", ], "warn": Array [], } ` exports[`test/lib/commands/doctor.js TAP windows skips permissions checks > no permissions checks 1`] = ` -Check Value Recommendation/Notes -npm ping ok -npm -v ok current: v1.0.0, latest: v1.0.0 -node -v ok current: v1.0.0, recommended: v1.0.0 -npm config get registry ok using default registry (https://registry.npmjs.org/) -git executable in PATH ok /path/to/git -global bin folder in PATH ok {CWD}/global +Connecting to the registry +Ok +Checking npm version +Ok +current: v1.0.0, latest: v1.0.0 +Checking node version +Ok +current: v1.0.0, recommended: v1.0.0 +Checking configured npm registry +Ok +using default registry (https://registry.npmjs.org/) +Checking for git executable in PATH +Ok +/path/to/git +Checking for global bin folder in PATH +Ok +{CWD}/global ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/fund.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/fund.js.test.cjs index 011315a9211ef0..28ffd76d5c7360 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/fund.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/fund.js.test.cjs @@ -12,16 +12,15 @@ Run \`npm fund [] --which=1\`, for example, to open the first fund ` exports[`test/lib/commands/fund.js TAP fund colors > should print output with color info 1`] = ` -test-fund-colors@1.0.0 -+-- http://example.com/a -| \`-- a@1.0.0 -\`-- http://example.com/b - | \`-- b@1.0.0, c@1.0.0 - +-- http://example.com/d - | \`-- d@1.0.0 - \`-- http://example.com/e - \`-- e@1.0.0 - +test-fund-colors@1.0.0 ++-- http://example.com/a +| \`-- a@1.0.0 +\`-- http://example.com/b + | \`-- b@1.0.0, c@1.0.0 + +-- http://example.com/d + | \`-- d@1.0.0 + \`-- http://example.com/e + \`-- e@1.0.0 ` exports[`test/lib/commands/fund.js TAP fund containing multi-level nested deps with no funding > should omit dependencies with no funding declared 1`] = ` @@ -30,19 +29,16 @@ nested-no-funding-packages@1.0.0 | \`-- lorem@1.0.0 \`-- http://example.com/donate \`-- bar@1.0.0 - ` exports[`test/lib/commands/fund.js TAP fund in which same maintainer owns all its deps > should print stack packages together 1`] = ` http://example.com/donate \`-- maintainer-owns-all-deps@1.0.0, dep-foo@1.0.0, dep-sub-foo@1.0.0, dep-bar@1.0.0 - ` exports[`test/lib/commands/fund.js TAP fund pkg missing version number > should print name only 1`] = ` http://example.com/foo \`-- foo - ` exports[`test/lib/commands/fund.js TAP fund using bad which value: index too high > should print message about invalid which 1`] = ` @@ -61,7 +57,6 @@ Run \`npm fund [] --which=1\`, for example, to open the first fund exports[`test/lib/commands/fund.js TAP fund with no package containing funding > should print empty funding info 1`] = ` no-funding-package@0.0.0 - ` exports[`test/lib/commands/fund.js TAP sub dep with fund info and a parent with no funding info > should nest sub dep as child of root 1`] = ` @@ -70,7 +65,6 @@ test-multiple-funding-sources@1.0.0 | \`-- b@1.0.0 \`-- http://example.com/c \`-- c@1.0.0 - ` exports[`test/lib/commands/fund.js TAP workspaces filter funding info by a specific workspace name > should display only filtered workspace name and its deps 1`] = ` @@ -79,7 +73,6 @@ workspaces-support@1.0.0 | \`-- a@1.0.0 \`-- http://example.com/c \`-- c@1.0.0 - ` exports[`test/lib/commands/fund.js TAP workspaces filter funding info by a specific workspace path > should display only filtered workspace name and its deps 1`] = ` @@ -88,5 +81,4 @@ workspaces-support@1.0.0 | \`-- a@1.0.0 \`-- http://example.com/c \`-- c@1.0.0 - ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/init.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/init.js.test.cjs index 821193a55e1a98..eae04d77d2e82e 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/init.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/init.js.test.cjs @@ -20,5 +20,6 @@ Press ^C at any time to quit. exports[`test/lib/commands/init.js TAP workspaces no args -- yes > should print helper info 1`] = ` + added 1 package in {TIME} ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs index a6e4472cae95a1..184259eafff836 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs @@ -42,14 +42,12 @@ test-npm-ls-ignore-missing-optional@1.2.3 {CWD}/prefix +-- UNMET DEPENDENCY prod-missing@1 +-- prod-ok@1.2.3 \`-- prod-wrong@3.2.1 invalid: "1" from the root project - ` exports[`test/lib/commands/ls.js TAP ls --depth=0 > should output tree containing only top-level dependencies 1`] = ` test-npm-ls@1.0.0 {CWD}/prefix +-- chai@1.0.0 \`-- foo@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls --depth=1 > should output tree containing top-level deps and their deps only 1`] = ` @@ -57,7 +55,6 @@ test-npm-ls@1.0.0 {CWD}/prefix +-- a@1.0.0 | \`-- b@1.0.0 \`-- e@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls --dev > should output tree containing dev deps 1`] = ` @@ -65,13 +62,11 @@ test-npm-ls@1.0.0 {CWD}/prefix \`-- dev-dep@1.0.0 \`-- foo@1.0.0 \`-- dog@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls --link > should output tree containing linked deps 1`] = ` test-npm-ls@1.0.0 {CWD}/prefix \`-- linked-dep@1.0.0 -> ./linked-dep - ` exports[`test/lib/commands/ls.js TAP ls --long --depth=0 > should output tree containing top-level deps with descriptions 1`] = ` @@ -88,7 +83,6 @@ test-npm-ls@1.0.0 | Peer-dep description here \`-- prod-dep@1.0.0 A PROD dep kind of dep - ` exports[`test/lib/commands/ls.js TAP ls --long > should output tree info with descriptions 1`] = ` @@ -111,7 +105,6 @@ test-npm-ls@1.0.0 | A PROD dep kind of dep \`-- dog@2.0.0 A dep that bars - ` exports[`test/lib/commands/ls.js TAP ls --parseable --depth=0 > should output tree containing only top-level dependencies 1`] = ` @@ -318,21 +311,19 @@ test-npm-ls@1.0.0 {CWD}/prefix +-- optional-dep@1.0.0 \`-- prod-dep@1.0.0 \`-- dog@2.0.0 - ` exports[`test/lib/commands/ls.js TAP ls broken resolved field > should NOT print git refs in output tree 1`] = ` npm-broken-resolved-field-test@1.0.0 {CWD}/prefix \`-- a@1.0.1 - ` exports[`test/lib/commands/ls.js TAP ls colored output > should output tree containing color info 1`] = ` test-npm-ls@1.0.0 {CWD}/prefix -+-- chai@1.0.0 extraneous -+-- foo@1.0.0 invalid: "^2.0.0" from the root project ++-- chai@1.0.0 extraneous ++-- foo@1.0.0 invalid: "^2.0.0" from the root project | \`-- dog@1.0.0 -\`-- UNMET DEPENDENCY ipsum@^1.0.0 +\`-- UNMET DEPENDENCY ipsum@^1.0.0  ` @@ -341,14 +332,13 @@ test-npm-ls@1.0.0 {CWD}/prefix \`-- a@1.0.0 \`-- b@1.0.0 \`-- a@1.0.0 deduped - ` exports[`test/lib/commands/ls.js TAP ls cycle deps with filter args > should print tree output containing deduped ref 1`] = ` test-npm-ls@1.0.0 {CWD}/prefix -\`-- a@1.0.0 +\`-- a@1.0.0  \`-- b@1.0.0 - \`-- a@1.0.0 deduped + \`-- a@1.0.0 deduped  ` @@ -357,20 +347,17 @@ test-npm-ls@1.0.0 {CWD}/prefix +-- a@1.0.0 | \`-- UNMET DEPENDENCY b@^1.0.0 \`-- UNMET DEPENDENCY b@^1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls default --depth value should be 0 > should output tree containing only top-level dependencies 1`] = ` test-npm-ls@1.0.0 {CWD}/prefix +-- chai@1.0.0 \`-- foo@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls empty location > should print empty result 1`] = ` {CWD}/prefix \`-- (empty) - ` exports[`test/lib/commands/ls.js TAP ls extraneous deps > should output containing problems info 1`] = ` @@ -378,19 +365,16 @@ test-npm-ls@1.0.0 {CWD}/prefix +-- chai@1.0.0 extraneous \`-- foo@1.0.0 \`-- dog@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls filter pkg arg using depth option should list a in top-level only > output 1`] = ` test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/prefix \`-- a@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls filter pkg arg using depth option should print empty results msg > output 1`] = ` test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/prefix \`-- (empty) - ` exports[`test/lib/commands/ls.js TAP ls filter pkg arg using depth option should print expected result > output 1`] = ` @@ -398,7 +382,6 @@ test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/prefix \`-- b@1.0.0 \`-- c@1.0.0 \`-- d@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls filtering by child of missing dep > should print tree and not duplicate child of missing items 1`] = ` @@ -408,13 +391,11 @@ filter-by-child-of-missing-dep@1.0.0 {CWD}/prefix +-- c@1.0.0 extraneous \`-- d@1.0.0 extraneous \`-- c@2.0.0 extraneous - ` exports[`test/lib/commands/ls.js TAP ls from and resolved properties > should not be printed in tree output 1`] = ` test-npm-ls@1.0.0 {CWD}/prefix \`-- simple-output@2.1.1 - ` exports[`test/lib/commands/ls.js TAP ls global > should print tree and not mark top-level items extraneous 1`] = ` @@ -422,14 +403,13 @@ exports[`test/lib/commands/ls.js TAP ls global > should print tree and not mark +-- a@1.0.0 \`-- b@1.0.0 \`-- c@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls invalid deduped dep > should output tree signaling mismatching peer dep in problems 1`] = ` invalid-deduped-dep@1.0.0 {CWD}/prefix +-- a@1.0.0 -| \`-- b@1.0.0 deduped invalid: "^2.0.0" from the root project, "^2.0.0" from node_modules/a -\`-- b@1.0.0 invalid: "^2.0.0" from the root project, "^2.0.0" from node_modules/a +| \`-- b@1.0.0 deduped invalid: "^2.0.0" from the root project, "^2.0.0" from node_modules/a +\`-- b@1.0.0 invalid: "^2.0.0" from the root project, "^2.0.0" from node_modules/a  ` @@ -443,20 +423,17 @@ test-npm-ls@1.0.0 {CWD}/prefix +-- peer-dep@1.0.0 invalid: "^2.0.0" from the root project \`-- prod-dep@1.0.0 \`-- dog@2.0.0 - ` exports[`test/lib/commands/ls.js TAP ls json read problems > should print empty result 1`] = ` {CWD}/prefix \`-- (empty) - ` exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should filter by parent folder workspace config > output 1`] = ` workspaces-tree@1.0.0 {CWD}/prefix +-- e@1.0.0 -> ./group/e \`-- f@1.0.0 -> ./group/f - ` exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should filter single workspace > output 1`] = ` @@ -464,7 +441,6 @@ workspaces-tree@1.0.0 {CWD}/prefix +-- a@1.0.0 -> ./a | \`-- d@1.0.0 deduped -> ./d \`-- d@1.0.0 -> ./d - ` exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should filter using workspace config > output 1`] = ` @@ -475,7 +451,6 @@ workspaces-tree@1.0.0 {CWD}/prefix \`-- d@1.0.0 -> ./d \`-- foo@1.1.1 \`-- bar@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should inlude root and specified workspace > output 1`] = ` @@ -484,7 +459,6 @@ workspaces-tree@1.0.0 {CWD}/prefix | \`-- foo@1.1.1 | \`-- bar@1.0.0 \`-- pacote@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should list --all workspaces properly > output 1`] = ` @@ -500,7 +474,6 @@ workspaces-tree@1.0.0 {CWD}/prefix +-- e@1.0.0 -> ./group/e +-- f@1.0.0 -> ./group/f \`-- pacote@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should list only prod deps of workspaces > output 1`] = ` @@ -515,20 +488,19 @@ workspaces-tree@1.0.0 {CWD}/prefix +-- e@1.0.0 -> ./group/e +-- f@1.0.0 -> ./group/f \`-- pacote@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should list workspaces properly with default configs > output 1`] = ` workspaces-tree@1.0.0 {CWD}/prefix -+-- a@1.0.0 -> ./a ++-- a@1.0.0 -> ./a | +-- baz@1.0.0 | +-- c@1.0.0 -| \`-- d@1.0.0 deduped -> ./d -+-- b@1.0.0 -> ./b -+-- d@1.0.0 -> ./d +| \`-- d@1.0.0 deduped -> ./d ++-- b@1.0.0 -> ./b ++-- d@1.0.0 -> ./d | \`-- foo@1.1.1 -+-- e@1.0.0 -> ./group/e -+-- f@1.0.0 -> ./group/f ++-- e@1.0.0 -> ./group/e ++-- f@1.0.0 -> ./group/f \`-- pacote@1.0.0  ` @@ -544,7 +516,6 @@ workspaces-tree@1.0.0 {CWD}/prefix \`-- d@1.0.0 -> ./d \`-- foo@1.1.1 \`-- bar@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls missing package.json > should output tree missing name/version of top-level package 1`] = ` @@ -553,7 +524,6 @@ exports[`test/lib/commands/ls.js TAP ls missing package.json > should output tre +-- dog@1.0.0 extraneous \`-- foo@1.0.0 extraneous \`-- dog@1.0.0 deduped - ` exports[`test/lib/commands/ls.js TAP ls missing/invalid/extraneous > should output tree containing missing, invalid, extraneous labels 1`] = ` @@ -562,7 +532,6 @@ test-npm-ls@1.0.0 {CWD}/prefix +-- foo@1.0.0 invalid: "^2.0.0" from the root project | \`-- dog@1.0.0 \`-- UNMET DEPENDENCY ipsum@^1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls no args > should output tree representation of dependencies structure 1`] = ` @@ -570,20 +539,18 @@ test-npm-ls@1.0.0 {CWD}/prefix +-- chai@1.0.0 \`-- foo@1.0.0 \`-- dog@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls overridden dep > should contain overridden outout 1`] = ` test-overridden@1.0.0 {CWD}/prefix \`-- foo@1.0.0 \`-- bar@1.0.0 overridden - ` exports[`test/lib/commands/ls.js TAP ls overridden dep w/ color > should contain overridden outout 1`] = ` test-overridden@1.0.0 {CWD}/prefix \`-- foo@1.0.0 - \`-- bar@1.0.0 overridden + \`-- bar@1.0.0 overridden  ` @@ -592,13 +559,11 @@ print-deduped-symlinks@1.0.0 {CWD}/prefix +-- a@1.0.0 | \`-- b@1.0.0 deduped -> ./b \`-- b@1.0.0 -> ./b - ` exports[`test/lib/commands/ls.js TAP ls resolved points to git ref > should output tree containing git refs 1`] = ` test-npm-ls@1.0.0 {CWD}/prefix \`-- abbrev@1.1.1 (git+ssh://git@github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c) - ` exports[`test/lib/commands/ls.js TAP ls unmet optional dep > should output tree with empty entry for missing optional deps 1`] = ` @@ -607,8 +572,8 @@ exports[`test/lib/commands/ls.js TAP ls unmet optional dep > should output tree +-- dev-dep@1.0.0 | \`-- foo@1.0.0 | \`-- dog@1.0.0 -+-- UNMET OPTIONAL DEPENDENCY missing-optional-dep@^1.0.0 -+-- optional-dep@1.0.0 invalid: "^2.0.0" from the root project ++-- UNMET OPTIONAL DEPENDENCY missing-optional-dep@^1.0.0 ++-- optional-dep@1.0.0 invalid: "^2.0.0" from the root project +-- peer-dep@1.0.0 \`-- prod-dep@1.0.0  \`-- dog@2.0.0 @@ -618,22 +583,20 @@ exports[`test/lib/commands/ls.js TAP ls unmet optional dep > should output tree exports[`test/lib/commands/ls.js TAP ls unmet peer dep > should output tree signaling missing peer dep in problems 1`] = ` test-npm-ls@1.0.0 {CWD}/prefix \`-- UNMET DEPENDENCY peer-dep@* - ` exports[`test/lib/commands/ls.js TAP ls using aliases > should output tree containing aliases 1`] = ` test-npm-ls@1.0.0 {CWD}/prefix \`-- a@npm:b@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls with args and dedupe entries > should print tree output containing deduped ref 1`] = ` dedupe-entries@1.0.0 {CWD}/prefix +-- @npmcli/a@1.0.0 -| \`-- @npmcli/b@1.1.2 deduped -+-- @npmcli/b@1.1.2 +| \`-- @npmcli/b@1.1.2 deduped ++-- @npmcli/b@1.1.2 \`-- @npmcli/c@1.0.0 - \`-- @npmcli/b@1.1.2 deduped + \`-- @npmcli/b@1.1.2 deduped  ` @@ -644,18 +607,16 @@ dedupe-entries@1.0.0 {CWD}/prefix +-- @npmcli/b@1.1.2 | \`-- @npmcli/c@1.0.0 deduped \`-- @npmcli/c@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls with dot filter arg > should output tree contaning only occurrences of filtered by package and colored output 1`] = ` test-npm-ls@1.0.0 {CWD}/prefix \`-- (empty) - ` exports[`test/lib/commands/ls.js TAP ls with filter arg > should output tree contaning only occurrences of filtered by package and colored output 1`] = ` test-npm-ls@1.0.0 {CWD}/prefix -\`-- chai@1.0.0 +\`-- chai@1.0.0  ` @@ -663,13 +624,11 @@ exports[`test/lib/commands/ls.js TAP ls with filter arg nested dep > should outp test-npm-ls@1.0.0 {CWD}/prefix \`-- foo@1.0.0 \`-- dog@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls with missing filter arg > should output tree containing no dependencies info 1`] = ` test-npm-ls@1.0.0 {CWD}/prefix \`-- (empty) - ` exports[`test/lib/commands/ls.js TAP ls with multiple filter args > should output tree contaning only occurrences of multiple filtered packages and their ancestors 1`] = ` @@ -677,7 +636,6 @@ test-npm-ls@1.0.0 {CWD}/prefix +-- chai@1.0.0 \`-- foo@1.0.0 \`-- dog@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls with no args dedupe entries > should print tree output containing deduped ref 1`] = ` @@ -687,7 +645,6 @@ dedupe-entries@1.0.0 {CWD}/prefix +-- @npmcli/b@1.1.2 \`-- @npmcli/c@1.0.0 \`-- @npmcli/b@1.1.2 deduped - ` exports[`test/lib/commands/ls.js TAP ls with no args dedupe entries and not displaying all > should print tree output containing deduped ref 1`] = ` @@ -695,14 +652,12 @@ dedupe-entries@1.0.0 {CWD}/prefix +-- @npmcli/a@1.0.0 +-- @npmcli/b@1.1.2 \`-- @npmcli/c@1.0.0 - ` exports[`test/lib/commands/ls.js TAP ls workspace and missing optional dep > should omit missing optional dep 1`] = ` root@ {CWD}/prefix +-- baz@1.0.0 -> ./baz \`-- foo@1.0.0 - ` exports[`test/lib/commands/ls.js TAP show multiple invalid reasons > ls result 1`] = ` @@ -713,5 +668,4 @@ test-npm-ls@1.0.0 {CWD}/prefix | \`-- dog@1.0.0 deduped invalid: "^1.2.3" from the root project, "^2.0.0" from node_modules/cat, "2.x" from node_modules/chai \`-- dog@1.0.0 invalid: "^1.2.3" from the root project, "^2.0.0" from node_modules/cat, "2.x" from node_modules/chai \`-- cat@1.0.0 deduped invalid: "^2.0.0" from the root project - ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/outdated.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/outdated.js.test.cjs index a72338b0bacc56..ec0298fcf4fa7b 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/outdated.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/outdated.js.test.cjs @@ -93,25 +93,25 @@ theta MISSING 1.0.1 1.0.1 - prefix dependencies ` exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --omit=dev --omit=peer > must match snapshot 1`] = ` -Package Current Wanted Latest Location Depended by -cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix -dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix -theta MISSING 1.0.1 1.0.1 - prefix +Package Current Wanted Latest Location Depended by +cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix +dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix +theta MISSING 1.0.1 1.0.1 - prefix ` exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --omit=dev > must match snapshot 1`] = ` -Package Current Wanted Latest Location Depended by -cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix -chai 1.0.0 1.0.1 1.0.1 node_modules/chai prefix -dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix -theta MISSING 1.0.1 1.0.1 - prefix +Package Current Wanted Latest Location Depended by +cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix +chai 1.0.0 1.0.1 1.0.1 node_modules/chai prefix +dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix +theta MISSING 1.0.1 1.0.1 - prefix ` exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --omit=prod > must match snapshot 1`] = ` -Package Current Wanted Latest Location Depended by -cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix -chai 1.0.0 1.0.1 1.0.1 node_modules/chai prefix -dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix +Package Current Wanted Latest Location Depended by +cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix +chai 1.0.0 1.0.1 1.0.1 node_modules/chai prefix +dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix ` exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --parseable --long > must match snapshot 1`] = ` @@ -129,11 +129,11 @@ exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated ` exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated > must match snapshot 1`] = ` -Package Current Wanted Latest Location Depended by -cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix -chai 1.0.0 1.0.1 1.0.1 node_modules/chai prefix -dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix -theta MISSING 1.0.1 1.0.1 - prefix +Package Current Wanted Latest Location Depended by +cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix +chai 1.0.0 1.0.1 1.0.1 node_modules/chai prefix +dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix +theta MISSING 1.0.1 1.0.1 - prefix ` exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated global > must match snapshot 1`] = ` @@ -232,8 +232,8 @@ exports[`test/lib/commands/outdated.js TAP workspaces should display ws outdated ` exports[`test/lib/commands/outdated.js TAP workspaces should highlight ws in dependend by section > output 1`] = ` -Package Current Wanted Latest Location Depended by -cat 1.0.0 1.0.1 1.0.1 node_modules/cat a@1.0.0 -dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix -theta MISSING 1.0.1 1.0.1 - c@1.0.0 +Package Current Wanted Latest Location Depended by +cat 1.0.0 1.0.1 1.0.1 node_modules/cat a@1.0.0 +dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix +theta MISSING 1.0.1 1.0.1 - c@1.0.0 ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/pack.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/pack.js.test.cjs index 5cdcdd9a8d08a5..f8c35e1c2c1fd2 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/pack.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/pack.js.test.cjs @@ -7,64 +7,52 @@ 'use strict' exports[`test/lib/commands/pack.js TAP dry run > logs pack contents 1`] = ` Array [ - undefined, "package: test-package@1.0.0", - undefined, + "Tarball Contents", "41B package.json", - undefined, - String( - name: test-package - version: 1.0.0 - filename: test-package-1.0.0.tgz - package size: {size} - unpacked size: 41 B - shasum: {sha} - integrity: {integrity} - total files: 1 - ), - "", + "Tarball Details", + "name: test-package", + "version: 1.0.0", + "filename: test-package-1.0.0.tgz", + "package size: {size}", + "unpacked size: 41 B", + "shasum: {sha}", + "integrity: {integrity} + "total files: 1", ] ` exports[`test/lib/commands/pack.js TAP foreground-scripts can still be set to false > logs pack contents 1`] = ` Array [ - undefined, "package: test-fg-scripts@0.0.0", - undefined, + "Tarball Contents", "110B package.json", - undefined, - String( - name: test-fg-scripts - version: 0.0.0 - filename: test-fg-scripts-0.0.0.tgz - package size: {size} - unpacked size: 110 B - shasum: {sha} - integrity: {integrity} - total files: 1 - ), - "", + "Tarball Details", + "name: test-fg-scripts", + "version: 0.0.0", + "filename: test-fg-scripts-0.0.0.tgz", + "package size: {size}", + "unpacked size: 110 B", + "shasum: {sha}", + "integrity: {integrity} + "total files: 1", ] ` exports[`test/lib/commands/pack.js TAP foreground-scripts defaults to true > logs pack contents 1`] = ` Array [ - undefined, "package: test-fg-scripts@0.0.0", - undefined, + "Tarball Contents", "110B package.json", - undefined, - String( - name: test-fg-scripts - version: 0.0.0 - filename: test-fg-scripts-0.0.0.tgz - package size: {size} - unpacked size: 110 B - shasum: {sha} - integrity: {integrity} - total files: 1 - ), - "", + "Tarball Details", + "name: test-fg-scripts", + "version: 0.0.0", + "filename: test-fg-scripts-0.0.0.tgz", + "package size: {size}", + "unpacked size: 110 B", + "shasum: {sha}", + "integrity: {integrity} + "total files: 1", ] ` @@ -121,30 +109,37 @@ Array [ "name": "@myscope/test-package", "shasum": "{sha}", "size": "{size}", - "unpackedSize": 50, + "unpackedSize": 88, "version": "1.0.0", }, ], ] ` +exports[`test/lib/commands/pack.js TAP should log scoped package output as valid json > stderr has banners 1`] = ` +Array [ + String( + + > @myscope/test-package@1.0.0 prepack + > echo prepack! + + ), +] +` + exports[`test/lib/commands/pack.js TAP should pack current directory with no arguments > logs pack contents 1`] = ` Array [ - undefined, "package: test-package@1.0.0", - undefined, + "Tarball Contents", "41B package.json", - undefined, - String( - name: test-package - version: 1.0.0 - filename: test-package-1.0.0.tgz - package size: {size} - unpacked size: 41 B - shasum: {sha} - integrity: {integrity} - total files: 1 - ), - "", + "Tarball Details", + "name: test-package", + "version: 1.0.0", + "filename: test-package-1.0.0.tgz", + "package size: {size}", + "unpacked size: 41 B", + "shasum: {sha}", + "integrity: {integrity} + "total files: 1", ] ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/profile.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/profile.js.test.cjs index 4530dbf95cec24..1fbb09de29f3ca 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/profile.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/profile.js.test.cjs @@ -31,19 +31,6 @@ exports[`test/lib/commands/profile.js TAP profile get multiple args default outp foo foo@github.com (verified) https://github.com/npm ` -exports[`test/lib/commands/profile.js TAP profile get no args --color > should output all profile info with color result 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 -` - exports[`test/lib/commands/profile.js TAP profile get no args --parseable > should output all profile info as parseable result 1`] = ` tfa auth-and-writes name foo diff --git a/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs index 4f947be5cf5dec..c13834d5d694cc 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs @@ -15,130 +15,55 @@ exports[`test/lib/commands/publish.js TAP bare _auth and registry config > new p 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: {size} - unpacked size: 87 B - shasum: {sha} - integrity: {integrity} - total files: 1 - ), - ], - Array [ - "", - "", - ], - Array [ - "", - "Publishing to https://registry.npmjs.org/ with tag latest and default access (dry-run)", - ], + "package: test-package@1.0.0", + "Tarball Contents", + "87B package.json", + "Tarball Details", + "name: test-package", + "version: 1.0.0", + "filename: test-package-1.0.0.tgz", + "package size: {size}", + "unpacked size: 87 B", + "shasum: {sha}", + "integrity: {integrity} + "total files: 1", + "Publishing to https://registry.npmjs.org/ with tag latest and default access (dry-run)", ] ` exports[`test/lib/commands/publish.js TAP foreground-scripts can still be set to false > must match snapshot 1`] = ` Array [ - Array [ - "", - ], - Array [ - "", - "package: test-fg-scripts@0.0.0", - ], - Array [ - "=== Tarball Contents ===", - ], - Array [ - "", - "110B package.json", - ], - Array [ - "=== Tarball Details ===", - ], - Array [ - "", - String( - name: test-fg-scripts - version: 0.0.0 - filename: test-fg-scripts-0.0.0.tgz - package size: {size} - unpacked size: 110 B - shasum: {sha} - integrity: {integrity} - total files: 1 - ), - ], - Array [ - "", - "", - ], - Array [ - "", - "Publishing to https://registry.npmjs.org/ with tag latest and default access (dry-run)", - ], + "package: test-fg-scripts@0.0.0", + "Tarball Contents", + "110B package.json", + "Tarball Details", + "name: test-fg-scripts", + "version: 0.0.0", + "filename: test-fg-scripts-0.0.0.tgz", + "package size: {size}", + "unpacked size: 110 B", + "shasum: {sha}", + "integrity: {integrity} + "total files: 1", + "Publishing to https://registry.npmjs.org/ with tag latest and default access (dry-run)", ] ` exports[`test/lib/commands/publish.js TAP foreground-scripts defaults to true > must match snapshot 1`] = ` Array [ - Array [ - "", - ], - Array [ - "", - "package: test-fg-scripts@0.0.0", - ], - Array [ - "=== Tarball Contents ===", - ], - Array [ - "", - "110B package.json", - ], - Array [ - "=== Tarball Details ===", - ], - Array [ - "", - String( - name: test-fg-scripts - version: 0.0.0 - filename: test-fg-scripts-0.0.0.tgz - package size: {size} - unpacked size: 110 B - shasum: {sha} - integrity: {integrity} - total files: 1 - ), - ], - Array [ - "", - "", - ], - Array [ - "", - "Publishing to https://registry.npmjs.org/ with tag latest and default access (dry-run)", - ], + "package: test-fg-scripts@0.0.0", + "Tarball Contents", + "110B package.json", + "Tarball Details", + "name: test-fg-scripts", + "version: 0.0.0", + "filename: test-fg-scripts-0.0.0.tgz", + "package size: {size}", + "unpacked size: 110 B", + "shasum: {sha}", + "integrity: {integrity} + "total files: 1", + "Publishing to https://registry.npmjs.org/ with tag latest and default access (dry-run)", ] ` @@ -156,10 +81,7 @@ exports[`test/lib/commands/publish.js TAP ignore-scripts > new package version 1 exports[`test/lib/commands/publish.js TAP json > must match snapshot 1`] = ` Array [ - Array [ - "", - "Publishing to https://registry.npmjs.org/ with tag latest and default access", - ], + "Publishing to https://registry.npmjs.org/ with tag latest and default access", ] ` @@ -332,21 +254,12 @@ exports[`test/lib/commands/publish.js TAP no auth dry-run > must match snapshot exports[`test/lib/commands/publish.js TAP no auth dry-run > warns about auth being needed 1`] = ` Array [ - Array [ - "publish", - "npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", - ], - Array [ - "publish", - String( - errors corrected: - Removed invalid "scripts" - ), - ], - Array [ - "", - "This command requires you to be logged in to https://registry.npmjs.org/ (dry-run)", - ], + "publish npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", + String( + publish errors corrected: + publish Removed invalid "scripts" + ), + "This command requires you to be logged in to https://registry.npmjs.org/ (dry-run)", ] ` @@ -356,44 +269,19 @@ exports[`test/lib/commands/publish.js TAP prioritize CLI flags over publishConfi exports[`test/lib/commands/publish.js TAP public access > must match snapshot 1`] = ` Array [ - Array [ - "", - ], - Array [ - "", - "package: @npm/test-package@1.0.0", - ], - Array [ - "=== Tarball Contents ===", - ], - Array [ - "", - "55B package.json", - ], - Array [ - "=== Tarball Details ===", - ], - Array [ - "", - String( - name: @npm/test-package - version: 1.0.0 - filename: npm-test-package-1.0.0.tgz - package size: {size} - unpacked size: 55 B - shasum: {sha} - integrity: {integrity} - total files: 1 - ), - ], - Array [ - "", - "", - ], - Array [ - "", - "Publishing to https://registry.npmjs.org/ with tag latest and public access", - ], + "package: @npm/test-package@1.0.0", + "Tarball Contents", + "55B package.json", + "Tarball Details", + "name: @npm/test-package", + "version: 1.0.0", + "filename: npm-test-package-1.0.0.tgz", + "package size: {size}", + "unpacked size: 55 B", + "shasum: {sha}", + "integrity: {integrity} + "total files: 1", + "Publishing to https://registry.npmjs.org/ with tag latest and public access", ] ` @@ -411,44 +299,19 @@ exports[`test/lib/commands/publish.js TAP respects publishConfig.registry, runs exports[`test/lib/commands/publish.js TAP restricted access > must match snapshot 1`] = ` Array [ - Array [ - "", - ], - Array [ - "", - "package: @npm/test-package@1.0.0", - ], - Array [ - "=== Tarball Contents ===", - ], - Array [ - "", - "55B package.json", - ], - Array [ - "=== Tarball Details ===", - ], - Array [ - "", - String( - name: @npm/test-package - version: 1.0.0 - filename: npm-test-package-1.0.0.tgz - package size: {size} - unpacked size: 55 B - shasum: {sha} - integrity: {integrity} - total files: 1 - ), - ], - Array [ - "", - "", - ], - Array [ - "", - "Publishing to https://registry.npmjs.org/ with tag latest and restricted access", - ], + "package: @npm/test-package@1.0.0", + "Tarball Contents", + "55B package.json", + "Tarball Details", + "name: @npm/test-package", + "version: 1.0.0", + "filename: npm-test-package-1.0.0.tgz", + "package size: {size}", + "unpacked size: 55 B", + "shasum: {sha}", + "integrity: {integrity} + "total files: 1", + "Publishing to https://registry.npmjs.org/ with tag latest and restricted access", ] ` @@ -462,47 +325,22 @@ exports[`test/lib/commands/publish.js TAP scoped _auth config scoped registry > 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: {size} - unpacked size: 124 B - shasum: {sha} - integrity: {integrity} - total files: 2 - ), - ], - Array [ - "", - "", - ], - Array [ - "", - "Publishing to https://registry.npmjs.org/ with tag latest and default access", - ], + "package: test-tar-package@1.0.0", + "Tarball Contents", + String( + 26B index.js + 98B package.json + ), + "Tarball Details", + "name: test-tar-package", + "version: 1.0.0", + "filename: test-tar-package-1.0.0.tgz", + "package size: {size}", + "unpacked size: 124 B", + "shasum: {sha}", + "integrity: {integrity} + "total files: 2", + "Publishing to https://registry.npmjs.org/ with tag latest and default access", ] ` @@ -518,57 +356,30 @@ exports[`test/lib/commands/publish.js TAP workspaces all workspaces - color > al exports[`test/lib/commands/publish.js TAP workspaces all workspaces - color > warns about skipped private workspace in color 1`] = ` Array [ - Array [ - "publish", - "npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", - ], - Array [ - "publish", - String( - errors corrected: - Removed invalid "scripts" - "repository" was changed from a string to an object - ), - ], - Array [ - "publish", - "npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", - ], - Array [ - "publish", - String( - errors corrected: - Removed invalid "scripts" - "repository" was changed from a string to an object - "repository.url" was normalized to "git+https://github.com/npm/workspace-b.git" - ), - ], - Array [ - "publish", - "npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", - ], - Array [ - "publish", - String( - errors corrected: - Removed invalid "scripts" - ), - ], - Array [ - "publish", - "npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", - ], - Array [ - "publish", - String( - errors corrected: - Removed invalid "scripts" - ), - ], - Array [ - "publish", - "Skipping workspace \\u001b[32mworkspace-p\\u001b[39m, marked as \\u001b[1mprivate\\u001b[22m", - ], + "\\u001b[94mpublish\\u001b[39m npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", + String( + \\u001b[94mpublish\\u001b[39m errors corrected: + \\u001b[94mpublish\\u001b[39m Removed invalid "scripts" + \\u001b[94mpublish\\u001b[39m "repository" was changed from a string to an object + ), + "\\u001b[94mpublish\\u001b[39m npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", + String( + \\u001b[94mpublish\\u001b[39m errors corrected: + \\u001b[94mpublish\\u001b[39m Removed invalid "scripts" + \\u001b[94mpublish\\u001b[39m "repository" was changed from a string to an object + \\u001b[94mpublish\\u001b[39m "repository.url" was normalized to "git+https://github.com/npm/workspace-b.git" + ), + "\\u001b[94mpublish\\u001b[39m npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", + String( + \\u001b[94mpublish\\u001b[39m errors corrected: + \\u001b[94mpublish\\u001b[39m Removed invalid "scripts" + ), + "\\u001b[94mpublish\\u001b[39m npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", + String( + \\u001b[94mpublish\\u001b[39m errors corrected: + \\u001b[94mpublish\\u001b[39m Removed invalid "scripts" + ), + "\\u001b[94mpublish\\u001b[39m Skipping workspace \\u001b[36mworkspace-p\\u001b[39m, marked as \\u001b[1mprivate\\u001b[22m", ] ` @@ -580,57 +391,30 @@ exports[`test/lib/commands/publish.js TAP workspaces all workspaces - no color > exports[`test/lib/commands/publish.js TAP workspaces all workspaces - no color > warns about skipped private workspace 1`] = ` Array [ - Array [ - "publish", - "npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", - ], - Array [ - "publish", - String( - errors corrected: - Removed invalid "scripts" - "repository" was changed from a string to an object - ), - ], - Array [ - "publish", - "npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", - ], - Array [ - "publish", - String( - errors corrected: - Removed invalid "scripts" - "repository" was changed from a string to an object - "repository.url" was normalized to "git+https://github.com/npm/workspace-b.git" - ), - ], - Array [ - "publish", - "npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", - ], - Array [ - "publish", - String( - errors corrected: - Removed invalid "scripts" - ), - ], - Array [ - "publish", - "npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", - ], - Array [ - "publish", - String( - errors corrected: - Removed invalid "scripts" - ), - ], - Array [ - "publish", - "Skipping workspace workspace-p, marked as private", - ], + "publish npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", + String( + publish errors corrected: + publish Removed invalid "scripts" + publish "repository" was changed from a string to an object + ), + "publish npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", + String( + publish errors corrected: + publish Removed invalid "scripts" + publish "repository" was changed from a string to an object + publish "repository.url" was normalized to "git+https://github.com/npm/workspace-b.git" + ), + "publish npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", + String( + publish errors corrected: + publish Removed invalid "scripts" + ), + "publish npm auto-corrected some errors in your package.json when publishing. Please run \\"npm pkg fix\\" to address these errors.", + String( + publish errors corrected: + publish Removed invalid "scripts" + ), + "publish Skipping workspace workspace-p, marked as private", ] ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/search.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/search.js.test.cjs index 3fd12d699bd77f..d5485853545882 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/search.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/search.js.test.cjs @@ -5,142 +5,1022 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' -exports[`test/lib/commands/search.js TAP empty search results > should have expected search results 1`] = ` -No matches found for "foo" -` - 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 bad map 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 | -pkg-no-desc | | =lukekarrys | 2019-09-26 | 1.0.0 | +libnpm +Collection of programmatic APIs for the npm CLI +Version 3.0.1 published 2019-07-16 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm api package manager lib +https://npm.im/libnpm +libnpmaccess +programmatic library for \`npm access\` commands +Version 4.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: libnpmaccess +https://npm.im/libnpmaccess +@evocateur/libnpmaccess +programmatic library for \`npm access\` commands +Version 3.1.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmaccess +@evocateur/libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 1.2.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmpublish +libnpmorg +Programmatic api for \`npm org\` commands +Version 2.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: libnpm npm package manager api orgs teams +https://npm.im/libnpmorg +libnpmsearch +Programmatic API for searching in npm and compatible registries. +Version 3.1.0 published 2020-12-08 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm search api libnpm +https://npm.im/libnpmsearch +libnpmteam +npm Team management APIs +Version 2.0.2 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmteam +libnpmhook +programmatic API for managing npm registry hooks +Version 6.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm hooks registry npm api +https://npm.im/libnpmhook +libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 4.0.0 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmpublish +libnpmfund +Programmatic API for npm fund +Version 1.0.2 published 2020-12-08 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm npmcli libnpm cli git fund gitfund +https://npm.im/libnpmfund +@npmcli/map-workspaces +Retrieves a name:pathname Map for a given workspaces config +Version 1.0.1 published 2020-09-30 by ruyadorno +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm bad map npmcli libnpm cli workspaces map-workspaces +https://npm.im/@npmcli/map-workspaces +libnpmversion +library to do the things that 'npm version' does +Version 1.0.7 published 2020-11-04 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmversion +@types/libnpmsearch +TypeScript definitions for libnpmsearch +Version 2.0.1 published 2019-09-26 by types +Maintainers: types +https://npm.im/@types/libnpmsearch +pkg-no-desc +Version 1.0.0 published 2019-09-26 by lukekarrys +Maintainers: lukekarrys +https://npm.im/pkg-no-desc ` 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 bad map 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 |  -pkg-no-desc | | =lukekarrys | 2019-09-26 | 1.0.0 |  +libnpm +Collection of programmatic APIs for the npm CLI +Version 3.0.1 published 2019-07-16 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm api package manager lib +https://npm.im/libnpm +libnpmaccess +programmatic library for \`npm access\` commands +Version 4.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: libnpmaccess +https://npm.im/libnpmaccess +@evocateur/libnpmaccess +programmatic library for \`npm access\` commands +Version 3.1.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmaccess +@evocateur/libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 1.2.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmpublish +libnpmorg +Programmatic api for \`npm org\` commands +Version 2.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: libnpm npm package manager api orgs teams +https://npm.im/libnpmorg +libnpmsearch +Programmatic API for searching in npm and compatible registries. +Version 3.1.0 published 2020-12-08 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm search api libnpm +https://npm.im/libnpmsearch +libnpmteam +npm Team management APIs +Version 2.0.2 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmteam +libnpmhook +programmatic API for managing npm registry hooks +Version 6.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm hooks registry npm api +https://npm.im/libnpmhook +libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 4.0.0 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmpublish +libnpmfund +Programmatic API for npm fund +Version 1.0.2 published 2020-12-08 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm npmcli libnpm cli git fund gitfund +https://npm.im/libnpmfund +@npmcli/map-workspaces +Retrieves a name:pathname Map for a given workspaces config +Version 1.0.1 published 2020-09-30 by ruyadorno +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm bad map npmcli libnpm cli workspaces map-workspaces +https://npm.im/@npmcli/map-workspaces +libnpmversion +library to do the things that 'npm version' does +Version 1.0.7 published 2020-11-04 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmversion +@types/libnpmsearch +TypeScript definitions for libnpmsearch +Version 2.0.1 published 2019-09-26 by types +Maintainers: types +https://npm.im/@types/libnpmsearch +pkg-no-desc +Version 1.0.0 published 2019-09-26 by lukekarrys +Maintainers: lukekarrys +https://npm.im/pkg-no-desc ` 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 bad map 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 -pkg-no-desc =lukekarrys 2019-09-26 1.0.0 +libnpm Collection of programmatic APIs for the npm CLI 2019-07-16 3.0.1 npm,api,package manager,lib +libnpmaccess programmatic library for \`npm access\` commands 2020-11-03 4.0.1 libnpmaccess +@evocateur/libnpmaccess programmatic library for \`npm access\` commands 2019-07-16 3.1.2 +@evocateur/libnpmpublish Programmatic API for the bits behind npm publish and unpublish 2019-07-16 1.2.2 +libnpmorg Programmatic api for \`npm org\` commands 2020-11-03 2.0.1 libnpm,npm,package manager,api,orgs,teams +libnpmsearch Programmatic API for searching in npm and compatible registries. 2020-12-08 3.1.0 npm,search,api,libnpm +libnpmteam npm Team management APIs 2020-11-03 2.0.2 +libnpmhook programmatic API for managing npm registry hooks 2020-11-03 6.0.1 npm,hooks,registry,npm api +libnpmpublish Programmatic API for the bits behind npm publish and unpublish 2020-11-03 4.0.0 +libnpmfund Programmatic API for npm fund 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 2020-09-30 1.0.1 npm,,bad map,npmcli,libnpm,cli,workspaces,map-workspaces +libnpmversion library to do the things that 'npm version' does 2020-11-04 1.0.7 +@types/libnpmsearch TypeScript definitions for libnpmsearch 2019-09-26 2.0.1 +pkg-no-desc 2019-09-26 1.0.0 ` 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 | +foo +Version 1.0.0 published prehistoric by foo +Maintainers: foo +https://npm.im/foo +custom-registry +Version 1.0.0 published prehistoric by ??? +Maintainers: foo +https://npm.im/custom-registry +libnpmversion +Version 1.0.0 published prehistoric by foo +Maintainers: foo +https://npm.im/libnpmversion ` 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 bad map 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 | -pkg-no-desc | | =lukekarrys | 2019-09-26 | 1.0.0 | +libnpm +Collection of programmatic APIs for the npm CLI +Version 3.0.1 published 2019-07-16 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm api package manager lib +https://npm.im/libnpm +libnpmaccess +programmatic library for \`npm access\` commands +Version 4.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: libnpmaccess +https://npm.im/libnpmaccess +@evocateur/libnpmaccess +programmatic library for \`npm access\` commands +Version 3.1.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmaccess +@evocateur/libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 1.2.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmpublish +libnpmorg +Programmatic api for \`npm org\` commands +Version 2.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: libnpm npm package manager api orgs teams +https://npm.im/libnpmorg +libnpmsearch +Programmatic API for searching in npm and compatible registries. +Version 3.1.0 published 2020-12-08 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm search api libnpm +https://npm.im/libnpmsearch +libnpmteam +npm Team management APIs +Version 2.0.2 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmteam +libnpmhook +programmatic API for managing npm registry hooks +Version 6.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm hooks registry npm api +https://npm.im/libnpmhook +libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 4.0.0 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmpublish +libnpmfund +Programmatic API for npm fund +Version 1.0.2 published 2020-12-08 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm npmcli libnpm cli git fund gitfund +https://npm.im/libnpmfund +@npmcli/map-workspaces +Retrieves a name:pathname Map for a given workspaces config +Version 1.0.1 published 2020-09-30 by ruyadorno +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm bad map npmcli libnpm cli workspaces map-workspaces +https://npm.im/@npmcli/map-workspaces +libnpmversion +library to do the things that 'npm version' does +Version 1.0.7 published 2020-11-04 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmversion +@types/libnpmsearch +TypeScript definitions for libnpmsearch +Version 2.0.1 published 2019-09-26 by types +Maintainers: types +https://npm.im/@types/libnpmsearch +pkg-no-desc +Version 1.0.0 published 2019-09-26 by lukekarrys +Maintainers: lukekarrys +https://npm.im/pkg-no-desc +` + +exports[`test/lib/commands/search.js TAP search empty search results > should have expected search results 1`] = ` +No matches found for "foo" ` 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 bad map npmcli libnpm cli workspaces map-workspaces -@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 | -pkg-no-desc | | =lukekarrys | 2019-09-26 | 1.0.0 | +libnpm +Collection of programmatic APIs for the npm CLI +Version 3.0.1 published 2019-07-16 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm api package manager lib +https://npm.im/libnpm +libnpmaccess +programmatic library for \`npm access\` commands +Version 4.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: libnpmaccess +https://npm.im/libnpmaccess +@evocateur/libnpmaccess +programmatic library for \`npm access\` commands +Version 3.1.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmaccess +@evocateur/libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 1.2.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmpublish +libnpmorg +Programmatic api for \`npm org\` commands +Version 2.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: libnpm npm package manager api orgs teams +https://npm.im/libnpmorg +libnpmsearch +Programmatic API for searching in npm and compatible registries. +Version 3.1.0 published 2020-12-08 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm search api libnpm +https://npm.im/libnpmsearch +libnpmteam +npm Team management APIs +Version 2.0.2 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmteam +libnpmhook +programmatic API for managing npm registry hooks +Version 6.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm hooks registry npm api +https://npm.im/libnpmhook +libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 4.0.0 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmpublish +libnpmfund +Programmatic API for npm fund +Version 1.0.2 published 2020-12-08 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm npmcli libnpm cli git fund gitfund +https://npm.im/libnpmfund +@npmcli/map-workspaces +Retrieves a name:pathname Map for a given workspaces config +Version 1.0.1 published 2020-09-30 by ruyadorno +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm bad map npmcli libnpm cli workspaces map-workspaces +https://npm.im/@npmcli/map-workspaces +@types/libnpmsearch +TypeScript definitions for libnpmsearch +Version 2.0.1 published 2019-09-26 by types +Maintainers: types +https://npm.im/@types/libnpmsearch +pkg-no-desc +Version 1.0.0 published 2019-09-26 by lukekarrys +Maintainers: lukekarrys +https://npm.im/pkg-no-desc ` 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 bad map npmcli libnpm cli workspaces map-workspaces -@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 | -pkg-no-desc | | =lukekarrys | 2019-09-26 | 1.0.0 | +libnpm +Collection of programmatic APIs for the npm CLI +Version 3.0.1 published 2019-07-16 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm api package manager lib +https://npm.im/libnpm +libnpmaccess +programmatic library for \`npm access\` commands +Version 4.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: libnpmaccess +https://npm.im/libnpmaccess +@evocateur/libnpmaccess +programmatic library for \`npm access\` commands +Version 3.1.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmaccess +@evocateur/libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 1.2.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmpublish +libnpmorg +Programmatic api for \`npm org\` commands +Version 2.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: libnpm npm package manager api orgs teams +https://npm.im/libnpmorg +libnpmsearch +Programmatic API for searching in npm and compatible registries. +Version 3.1.0 published 2020-12-08 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm search api libnpm +https://npm.im/libnpmsearch +libnpmteam +npm Team management APIs +Version 2.0.2 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmteam +libnpmhook +programmatic API for managing npm registry hooks +Version 6.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm hooks registry npm api +https://npm.im/libnpmhook +libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 4.0.0 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmpublish +libnpmfund +Programmatic API for npm fund +Version 1.0.2 published 2020-12-08 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm npmcli libnpm cli git fund gitfund +https://npm.im/libnpmfund +@npmcli/map-workspaces +Retrieves a name:pathname Map for a given workspaces config +Version 1.0.1 published 2020-09-30 by ruyadorno +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm bad map npmcli libnpm cli workspaces map-workspaces +https://npm.im/@npmcli/map-workspaces +@types/libnpmsearch +TypeScript definitions for libnpmsearch +Version 2.0.1 published 2019-09-26 by types +Maintainers: types +https://npm.im/@types/libnpmsearch +pkg-no-desc +Version 1.0.0 published 2019-09-26 by lukekarrys +Maintainers: lukekarrys +https://npm.im/pkg-no-desc ` 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 bad map npmcli libnpm cli workspaces map-workspaces -@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 | -pkg-no-desc | | =lukekarrys | 2019-09-26 | 1.0.0 | +libnpm +Collection of programmatic APIs for the npm CLI +Version 3.0.1 published 2019-07-16 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm api package manager lib +https://npm.im/libnpm +libnpmaccess +programmatic library for \`npm access\` commands +Version 4.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: libnpmaccess +https://npm.im/libnpmaccess +@evocateur/libnpmaccess +programmatic library for \`npm access\` commands +Version 3.1.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmaccess +@evocateur/libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 1.2.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmpublish +libnpmorg +Programmatic api for \`npm org\` commands +Version 2.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: libnpm npm package manager api orgs teams +https://npm.im/libnpmorg +libnpmsearch +Programmatic API for searching in npm and compatible registries. +Version 3.1.0 published 2020-12-08 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm search api libnpm +https://npm.im/libnpmsearch +libnpmteam +npm Team management APIs +Version 2.0.2 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmteam +libnpmhook +programmatic API for managing npm registry hooks +Version 6.0.1 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm hooks registry npm api +https://npm.im/libnpmhook +libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 4.0.0 published 2020-11-03 by nlf +Maintainers: nlf ruyadorno darcyclarke isaacs +https://npm.im/libnpmpublish +libnpmfund +Programmatic API for npm fund +Version 1.0.2 published 2020-12-08 by isaacs +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm npmcli libnpm cli git fund gitfund +https://npm.im/libnpmfund +@npmcli/map-workspaces +Retrieves a name:pathname Map for a given workspaces config +Version 1.0.1 published 2020-09-30 by ruyadorno +Maintainers: nlf ruyadorno darcyclarke isaacs +Keywords: npm bad map npmcli libnpm cli workspaces map-workspaces +https://npm.im/@npmcli/map-workspaces +@types/libnpmsearch +TypeScript definitions for libnpmsearch +Version 2.0.1 published 2019-09-26 by types +Maintainers: types +https://npm.im/@types/libnpmsearch +pkg-no-desc +Version 1.0.0 published 2019-09-26 by lukekarrys +Maintainers: lukekarrys +https://npm.im/pkg-no-desc +` + +exports[`test/lib/commands/search.js TAP search exclude string json > results should not have libnpmversion 1`] = ` +Array [ + Object { + "author": Object { + "email": "kzm@zkat.tech", + "name": "Kat Marchán", + }, + "date": "2019-07-16T17:50:00.572Z", + "description": "Collection of programmatic APIs for the npm CLI", + "keywords": Array [ + "npm", + "api", + "package manager", + "lib", + ], + "links": Object { + "bugs": "https://github.com/npm/libnpm/issues", + "homepage": "https://github.com/npm/libnpm#readme", + "npm": "https://www.npmjs.com/package/libnpm", + "repository": "https://github.com/npm/libnpm", + }, + "maintainers": Array [ + Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + Object { + "email": "ruyadorno@hotmail.com", + "username": "ruyadorno", + }, + Object { + "email": "darcy@darcyclarke.me", + "username": "darcyclarke", + }, + Object { + "email": "i@izs.me", + "username": "isaacs", + }, + ], + "name": "libnpm", + "publisher": Object { + "email": "i@izs.me", + "username": "isaacs", + }, + "scope": "unscoped", + "version": "3.0.1", + }, + Object { + "author": Object { + "email": "kzm@sykosomatic.org", + "name": "Kat Marchán", + }, + "date": "2020-11-03T19:19:00.526Z", + "description": "programmatic library for \`npm access\` commands", + "keywords": "libnpmaccess", + "links": Object { + "bugs": "https://github.com/npm/libnpmaccess/issues", + "homepage": "https://npmjs.com/package/libnpmaccess", + "npm": "https://www.npmjs.com/package/libnpmaccess", + "repository": "https://github.com/npm/libnpmaccess", + }, + "maintainers": Array [ + Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + Object { + "email": "ruyadorno@hotmail.com", + "username": "ruyadorno", + }, + Object { + "email": "darcy@darcyclarke.me", + "username": "darcyclarke", + }, + Object { + "email": "i@izs.me", + "username": "isaacs", + }, + ], + "name": "libnpmaccess", + "publisher": Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + "scope": "unscoped", + "version": "4.0.1", + }, + Object { + "author": Object { + "email": "kzm@zkat.tech", + "name": "Kat Marchán", + }, + "date": "2019-07-16T19:43:33.959Z", + "description": "programmatic library for \`npm access\` commands", + "links": Object { + "bugs": "https://github.com/evocateur/libnpmaccess/issues", + "homepage": "https://npmjs.com/package/@evocateur/libnpmaccess", + "npm": "https://www.npmjs.com/package/%40evocateur%2Flibnpmaccess", + "repository": "https://github.com/evocateur/libnpmaccess", + }, + "maintainers": Array [ + Object { + "email": "daniel.stockman@gmail.com", + "username": "evocateur", + }, + ], + "name": "@evocateur/libnpmaccess", + "publisher": Object { + "email": "daniel.stockman@gmail.com", + "username": "evocateur", + }, + "scope": "evocateur", + "version": "3.1.2", + }, + Object { + "author": Object { + "email": "kzm@zkat.tech", + "name": "Kat Marchán", + }, + "date": "2019-07-16T19:40:40.850Z", + "description": "Programmatic API for the bits behind npm publish and unpublish", + "links": Object { + "bugs": "https://github.com/evocateur/libnpmpublish/issues", + "homepage": "https://npmjs.com/package/@evocateur/libnpmpublish", + "npm": "https://www.npmjs.com/package/%40evocateur%2Flibnpmpublish", + "repository": "https://github.com/evocateur/libnpmpublish", + }, + "maintainers": Array [ + Object { + "email": "daniel.stockman@gmail.com", + "username": "evocateur", + }, + ], + "name": "@evocateur/libnpmpublish", + "publisher": Object { + "email": "daniel.stockman@gmail.com", + "username": "evocateur", + }, + "scope": "evocateur", + "version": "1.2.2", + }, + Object { + "author": Object { + "email": "kzm@sykosomatic.org", + "name": "Kat Marchán", + }, + "date": "2020-11-03T19:21:57.757Z", + "description": "Programmatic api for \`npm org\` commands", + "keywords": Array [ + "libnpm", + "npm", + "package manager", + "api", + "orgs", + "teams", + ], + "links": Object { + "bugs": "https://github.com/npm/libnpmorg/issues", + "homepage": "https://npmjs.com/package/libnpmorg", + "npm": "https://www.npmjs.com/package/libnpmorg", + "repository": "https://github.com/npm/libnpmorg", + }, + "maintainers": Array [ + Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + Object { + "email": "ruyadorno@hotmail.com", + "username": "ruyadorno", + }, + Object { + "email": "darcy@darcyclarke.me", + "username": "darcyclarke", + }, + Object { + "email": "i@izs.me", + "username": "isaacs", + }, + ], + "name": "libnpmorg", + "publisher": Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + "scope": "unscoped", + "version": "2.0.1", + }, + Object { + "author": Object { + "email": "kzm@sykosomatic.org", + "name": "Kat Marchán", + }, + "date": "2020-12-08T23:54:18.374Z", + "description": "Programmatic API for searching in npm and compatible registries.", + "keywords": Array [ + "npm", + "search", + "api", + "libnpm", + ], + "links": Object { + "bugs": "https://github.com/npm/libnpmsearch/issues", + "homepage": "https://npmjs.com/package/libnpmsearch", + "npm": "https://www.npmjs.com/package/libnpmsearch", + "repository": "https://github.com/npm/libnpmsearch", + }, + "maintainers": Array [ + Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + Object { + "email": "ruyadorno@hotmail.com", + "username": "ruyadorno", + }, + Object { + "email": "darcy@darcyclarke.me", + "username": "darcyclarke", + }, + Object { + "email": "i@izs.me", + "username": "isaacs", + }, + ], + "name": "libnpmsearch", + "publisher": Object { + "email": "i@izs.me", + "username": "isaacs", + }, + "scope": "unscoped", + "version": "3.1.0", + }, + Object { + "author": Object { + "email": "kzm@zkat.tech", + "name": "Kat Marchán", + }, + "date": "2020-11-03T19:24:42.380Z", + "description": "npm Team management APIs", + "links": Object { + "bugs": "https://github.com/npm/libnpmteam/issues", + "homepage": "https://npmjs.com/package/libnpmteam", + "npm": "https://www.npmjs.com/package/libnpmteam", + "repository": "https://github.com/npm/libnpmteam", + }, + "maintainers": Array [ + Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + Object { + "email": "ruyadorno@hotmail.com", + "username": "ruyadorno", + }, + Object { + "email": "darcy@darcyclarke.me", + "username": "darcyclarke", + }, + Object { + "email": "i@izs.me", + "username": "isaacs", + }, + ], + "name": "libnpmteam", + "publisher": Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + "scope": "unscoped", + "version": "2.0.2", + }, + Object { + "author": Object { + "email": "kzm@sykosomatic.org", + "name": "Kat Marchán", + }, + "date": "2020-11-03T19:20:45.818Z", + "description": "programmatic API for managing npm registry hooks", + "keywords": Array [ + "npm", + "hooks", + "registry", + "npm api", + ], + "links": Object { + "bugs": "https://github.com/npm/libnpmhook/issues", + "homepage": "https://github.com/npm/libnpmhook#readme", + "npm": "https://www.npmjs.com/package/libnpmhook", + "repository": "https://github.com/npm/libnpmhook", + }, + "maintainers": Array [ + Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + Object { + "email": "ruyadorno@hotmail.com", + "username": "ruyadorno", + }, + Object { + "email": "darcy@darcyclarke.me", + "username": "darcyclarke", + }, + Object { + "email": "i@izs.me", + "username": "isaacs", + }, + ], + "name": "libnpmhook", + "publisher": Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + "scope": "unscoped", + "version": "6.0.1", + }, + Object { + "author": Object { + "email": "support@npmjs.com", + "name": "npm Inc.", + }, + "date": "2020-11-03T19:13:43.780Z", + "description": "Programmatic API for the bits behind npm publish and unpublish", + "links": Object { + "bugs": "https://github.com/npm/libnpmpublish/issues", + "homepage": "https://npmjs.com/package/libnpmpublish", + "npm": "https://www.npmjs.com/package/libnpmpublish", + "repository": "https://github.com/npm/libnpmpublish", + }, + "maintainers": Array [ + Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + Object { + "email": "ruyadorno@hotmail.com", + "username": "ruyadorno", + }, + Object { + "email": "darcy@darcyclarke.me", + "username": "darcyclarke", + }, + Object { + "email": "i@izs.me", + "username": "isaacs", + }, + ], + "name": "libnpmpublish", + "publisher": Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + "scope": "unscoped", + "version": "4.0.0", + }, + Object { + "author": Object { + "email": "support@npmjs.com", + "name": "npm Inc.", + }, + "date": "2020-12-08T23:22:00.213Z", + "description": "Programmatic API for npm fund", + "keywords": Array [ + "npm", + "npmcli", + "libnpm", + "cli", + "git", + "fund", + "gitfund", + ], + "links": Object { + "bugs": "https://github.com/npm/libnpmfund/issues", + "homepage": "https://github.com/npm/libnpmfund#readme", + "npm": "https://www.npmjs.com/package/libnpmfund", + "repository": "https://github.com/npm/libnpmfund", + }, + "maintainers": Array [ + Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + Object { + "email": "ruyadorno@hotmail.com", + "username": "ruyadorno", + }, + Object { + "email": "darcy@darcyclarke.me", + "username": "darcyclarke", + }, + Object { + "email": "i@izs.me", + "username": "isaacs", + }, + ], + "name": "libnpmfund", + "publisher": Object { + "email": "i@izs.me", + "username": "isaacs", + }, + "scope": "unscoped", + "version": "1.0.2", + }, + Object { + "author": Object { + "email": "support@npmjs.com", + "name": "npm Inc.", + }, + "date": "2020-09-30T15:16:29.017Z", + "description": "Retrieves a name:pathname Map for a given workspaces config", + "keywords": Array [ + "\\u001b[33mnpm\\u001b[39m", + "\\u001b]4;0;?\\u0007", + "\\u001b[Hbad map", + "npmcli", + "libnpm", + "cli", + "workspaces", + "map-workspaces", + ], + "links": Object { + "bugs": "https://github.com/npm/map-workspaces/issues", + "homepage": "https://github.com/npm/map-workspaces#readme", + "npm": "https://www.npmjs.com/package/%40npmcli%2Fmap-workspaces", + "repository": "https://github.com/npm/map-workspaces", + }, + "maintainers": Array [ + Object { + "email": "quitlahok@gmail.com", + "username": "nlf", + }, + Object { + "email": "ruyadorno@hotmail.com", + "username": "ruyadorno", + }, + Object { + "email": "darcy@darcyclarke.me", + "username": "darcyclarke", + }, + Object { + "email": "i@izs.me", + "username": "isaacs", + }, + ], + "name": "@npmcli/map-workspaces", + "publisher": Object { + "email": "ruyadorno@hotmail.com", + "username": "ruyadorno", + }, + "scope": "npmcli", + "version": "1.0.1", + }, + Object { + "date": "2019-09-26T22:24:28.713Z", + "description": "TypeScript definitions for libnpmsearch", + "links": Object { + "npm": "https://www.npmjs.com/package/%40types%2Flibnpmsearch", + }, + "maintainers": Array [ + Object { + "email": "ts-npm-types@microsoft.com", + "username": "types", + }, + ], + "name": "@types/libnpmsearch", + "publisher": Object { + "email": "ts-npm-types@microsoft.com", + "username": "types", + }, + "scope": "types", + "version": "2.0.1", + }, + Object { + "date": "2019-09-26T22:24:28.713Z", + "maintainers": Array [ + Object { + "email": "lukekarrys", + "username": "lukekarrys", + }, + ], + "name": "pkg-no-desc", + "publisher": Object { + "email": "lukekarrys", + "username": "lukekarrys", + }, + "scope": "unscoped", + "version": "1.0.0", + }, +] ` 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 | -pkg-no-desc | | =lukekarrys | 2019-09-26 | 1.0.0 | +@evocateur/libnpmaccess +programmatic library for \`npm access\` commands +Version 3.1.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmaccess +@evocateur/libnpmpublish +Programmatic API for the bits behind npm publish and unpublish +Version 1.2.2 published 2019-07-16 by evocateur +Maintainers: evocateur +https://npm.im/@evocateur/libnpmpublish +@types/libnpmsearch +TypeScript definitions for libnpmsearch +Version 2.0.1 published 2019-09-26 by types +Maintainers: types +https://npm.im/@types/libnpmsearch +pkg-no-desc +Version 1.0.0 published 2019-09-26 by lukekarrys +Maintainers: lukekarrys +https://npm.im/pkg-no-desc +` + +exports[`test/lib/commands/search.js TAP search no publisher > should have filtered expected search results 1`] = ` +custom-registry +Version 1.0.0 published prehistoric by ??? +Maintainers: foo +https://npm.im/custom-registry +libnpmversion +Version 1.0.0 published prehistoric by foo +Maintainers: foo +https://npm.im/libnpmversion ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/shrinkwrap.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/shrinkwrap.js.test.cjs index d97f13d2ed85c4..f0ac314925b28f 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/shrinkwrap.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/shrinkwrap.js.test.cjs @@ -22,7 +22,8 @@ exports[`test/lib/commands/shrinkwrap.js TAP with hidden lockfile ancient > must }, "logs": [ "created a lockfile as npm-shrinkwrap.json" - ] + ], + "warn": [] } ` @@ -46,6 +47,9 @@ exports[`test/lib/commands/shrinkwrap.js TAP with hidden lockfile ancient upgrad }, "logs": [ "created a lockfile as npm-shrinkwrap.json with version 3" + ], + "warn": [ + "Converting lock file (npm-shrinkwrap.json) from v1 -> v3" ] } ` @@ -68,7 +72,8 @@ exports[`test/lib/commands/shrinkwrap.js TAP with hidden lockfile existing > mus }, "logs": [ "created a lockfile as npm-shrinkwrap.json" - ] + ], + "warn": [] } ` @@ -91,6 +96,9 @@ exports[`test/lib/commands/shrinkwrap.js TAP with hidden lockfile existing downg }, "logs": [ "created a lockfile as npm-shrinkwrap.json with version 1" + ], + "warn": [ + "Converting lock file (npm-shrinkwrap.json) from v2 -> v1" ] } ` @@ -115,6 +123,9 @@ exports[`test/lib/commands/shrinkwrap.js TAP with hidden lockfile existing upgra }, "logs": [ "created a lockfile as npm-shrinkwrap.json with version 3" + ], + "warn": [ + "Converting lock file (npm-shrinkwrap.json) from v2 -> v3" ] } ` @@ -131,7 +142,8 @@ exports[`test/lib/commands/shrinkwrap.js TAP with nothing ancient > must match s }, "logs": [ "created a lockfile as npm-shrinkwrap.json with version 3" - ] + ], + "warn": [] } ` @@ -149,7 +161,8 @@ exports[`test/lib/commands/shrinkwrap.js TAP with nothing ancient upgrade > must }, "logs": [ "created a lockfile as npm-shrinkwrap.json with version 3" - ] + ], + "warn": [] } ` @@ -173,6 +186,9 @@ exports[`test/lib/commands/shrinkwrap.js TAP with npm-shrinkwrap.json ancient > }, "logs": [ "npm-shrinkwrap.json updated to version 3" + ], + "warn": [ + "Converting lock file (npm-shrinkwrap.json) from v1 -> v3" ] } ` @@ -199,6 +215,9 @@ exports[`test/lib/commands/shrinkwrap.js TAP with npm-shrinkwrap.json ancient up }, "logs": [ "npm-shrinkwrap.json updated to version 3" + ], + "warn": [ + "Converting lock file (npm-shrinkwrap.json) from v1 -> v3" ] } ` @@ -223,7 +242,8 @@ exports[`test/lib/commands/shrinkwrap.js TAP with npm-shrinkwrap.json existing > }, "logs": [ "npm-shrinkwrap.json up to date" - ] + ], + "warn": [] } ` @@ -244,6 +264,9 @@ exports[`test/lib/commands/shrinkwrap.js TAP with npm-shrinkwrap.json existing d }, "logs": [ "npm-shrinkwrap.json updated to version 1" + ], + "warn": [ + "Converting lock file (npm-shrinkwrap.json) from v2 -> v1" ] } ` @@ -270,6 +293,9 @@ exports[`test/lib/commands/shrinkwrap.js TAP with npm-shrinkwrap.json existing u }, "logs": [ "npm-shrinkwrap.json updated to version 3" + ], + "warn": [ + "Converting lock file (npm-shrinkwrap.json) from v2 -> v3" ] } ` @@ -294,6 +320,9 @@ exports[`test/lib/commands/shrinkwrap.js TAP with package-lock.json ancient > mu }, "logs": [ "package-lock.json has been renamed to npm-shrinkwrap.json and updated to version 3" + ], + "warn": [ + "Converting lock file (npm-shrinkwrap.json) from v1 -> v3" ] } ` @@ -320,6 +349,9 @@ exports[`test/lib/commands/shrinkwrap.js TAP with package-lock.json ancient upgr }, "logs": [ "package-lock.json has been renamed to npm-shrinkwrap.json and updated to version 3" + ], + "warn": [ + "Converting lock file (npm-shrinkwrap.json) from v1 -> v3" ] } ` @@ -344,7 +376,8 @@ exports[`test/lib/commands/shrinkwrap.js TAP with package-lock.json existing > m }, "logs": [ "package-lock.json has been renamed to npm-shrinkwrap.json" - ] + ], + "warn": [] } ` @@ -365,6 +398,9 @@ exports[`test/lib/commands/shrinkwrap.js TAP with package-lock.json existing dow }, "logs": [ "package-lock.json has been renamed to npm-shrinkwrap.json and updated to version 1" + ], + "warn": [ + "Converting lock file (npm-shrinkwrap.json) from v2 -> v1" ] } ` @@ -391,6 +427,9 @@ exports[`test/lib/commands/shrinkwrap.js TAP with package-lock.json existing upg }, "logs": [ "package-lock.json has been renamed to npm-shrinkwrap.json and updated to version 3" + ], + "warn": [ + "Converting lock file (npm-shrinkwrap.json) from v2 -> v3" ] } ` diff --git a/deps/npm/tap-snapshots/test/lib/commands/view.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/view.js.test.cjs index 3bda4e7de28531..3e06ecf5d054ee 100644 --- a/deps/npm/tap-snapshots/test/lib/commands/view.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/commands/view.js.test.cjs @@ -7,135 +7,129 @@ 'use strict' exports[`test/lib/commands/view.js TAP deprecated package with license, bugs, repository and other fields > must match snapshot 1`] = ` -green@1.0.0 | ACME | deps: 2 | versions: 2 +green@1.0.0 | ACME | deps: 2 | versions: 2 green is a very important color -DEPRECATED!! - true +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.0 GB +.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 +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 +latest: 1.0.0 ` exports[`test/lib/commands/view.js TAP deprecated package with unicode > must match snapshot 1`] = ` -green@1.0.0 | ACME | deps: 2 | versions: 2 +green@1.0.0 | ACME | deps: 2 | versions: 2 green is a very important color -DEPRECATED ⚠️ - true +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.0 GB +.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 +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 +latest: 1.0.0 ` exports[`test/lib/commands/view.js TAP package from git > must match snapshot 1`] = ` -green@1.0.0 | ACME | deps: 2 | versions: 2 +green@1.0.0 | ACME | deps: 2 | versions: 2 green is a very important color -DEPRECATED!! - true +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.0 GB +.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 +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 +latest: 1.0.0 ` exports[`test/lib/commands/view.js TAP package in cwd directory > must match snapshot 1`] = ` -blue@1.0.0 | Proprietary | deps: none | versions: 2 +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 dist-tags: -latest: 1.0.0 +latest: 1.0.0 published {TIME} ago ` 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 +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 dist-tags: -latest: 1.0.0 +latest: 1.0.0 published {TIME} ago ` exports[`test/lib/commands/view.js TAP package in cwd specific version > must match snapshot 1`] = ` -blue@1.0.0 | Proprietary | deps: none | versions: 2 +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 dist-tags: -latest: 1.0.0 +latest: 1.0.0 published {TIME} ago ` @@ -177,17 +171,17 @@ exports[`test/lib/commands/view.js TAP package with --json and semver range > mu 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 +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 +.tarball: http://hm.orange.com/1.0.0.tgz +.shasum: 123 +.integrity: --- +.unpackedSize: 1 B dist-tags: -latest: 1.0.0 +latest: 1.0.0 ` exports[`test/lib/commands/view.js TAP package with invalid version > must match snapshot 1`] = ` @@ -196,118 +190,114 @@ exports[`test/lib/commands/view.js TAP package with invalid version > must match 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 +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 +latest: 1.0.0 ` 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 +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 -10: 1.0.0 -11: 1.0.0 -12: 1.0.0 -13: 1.0.0 -14: 1.0.0 -15: 1.0.0 -16: 1.0.0 -17: 1.0.0 -18: 1.0.0 -19: 1.0.0 -1: 1.0.0 -20: 1.0.0 -21: 1.0.0 -22: 1.0.0 -23: 1.0.0 -2: 1.0.0 -3: 1.0.0 -4: 1.0.0 -5: 1.0.0 -6: 1.0.0 -7: 1.0.0 -8: 1.0.0 -9: 1.0.0 -(...and 1 more.) +0: 1.0.0 +10: 1.0.0 +11: 1.0.0 +12: 1.0.0 +13: 1.0.0 +14: 1.0.0 +15: 1.0.0 +16: 1.0.0 +17: 1.0.0 +18: 1.0.0 +19: 1.0.0 +1: 1.0.0 +20: 1.0.0 +21: 1.0.0 +22: 1.0.0 +23: 1.0.0 +2: 1.0.0 +3: 1.0.0 +4: 1.0.0 +5: 1.0.0 +6: 1.0.0 +7: 1.0.0 +8: 1.0.0 +9: 1.0.0 +(...and 1 more.) dist-tags: -latest: 1.0.0 +latest: 1.0.0 ` 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 +cyan@1.0.0 | Proprietary | deps: none | versions: 2 dist -.tarball: http://hm.cyan.com/1.0.0.tgz -.shasum: 123 -.integrity: --- -.unpackedSize: 1.0 MB +.tarball: http://hm.cyan.com/1.0.0.tgz +.shasum: 123 +.integrity: --- +.unpackedSize: 1.0 MB dist-tags: -latest: 1.0.0 +latest: 1.0.0 -published by claudia <claudia@cyan.com> +published by claudia <claudia@cyan.com> ` 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 +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 dist-tags: -latest: 1.0.0 +latest: 1.0.0 published {TIME} ago ` exports[`test/lib/commands/view.js TAP package with semver range > must match snapshot 1`] = ` -blue@1.0.0 | Proprietary | deps: none | versions: 2 +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 dist-tags: -latest: 1.0.0 +latest: 1.0.0 published {TIME} ago -blue@1.0.1 | Proprietary | deps: none | versions: 2 +blue@1.0.1 | Proprietary | deps: none | versions: 2 dist -.tarball: http://hm.blue.com/1.0.1.tgz -.shasum: 124 -.integrity: --- -.unpackedSize: 1.0 kB +.tarball: http://hm.blue.com/1.0.1.tgz +.shasum: 124 +.integrity: --- +.unpackedSize: 1.0 kB dist-tags: -latest: 1.0.0 +latest: 1.0.0 -published over a year from now +published over a year from now ` exports[`test/lib/commands/view.js TAP specific field names array field - 1 element > must match snapshot 1`] = ` @@ -435,43 +425,43 @@ 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@1.0.0 | ACME | deps: 2 | versions: 2 green is a very important color -DEPRECATED!! - true +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.0 GB +.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 +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 +latest: 1.0.0 -orange@1.0.0 | Proprietary | deps: none | versions: 2 -http://hm.orange.com +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 +.tarball: http://hm.orange.com/1.0.0.tgz +.shasum: 123 +.integrity: --- +.unpackedSize: 1 B dist-tags: -latest: 1.0.0 +latest: 1.0.0 ` exports[`test/lib/commands/view.js TAP workspaces all workspaces nonexistent field --json > must match snapshot 1`] = ` @@ -499,52 +489,50 @@ 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@1.0.0 | ACME | deps: 2 | versions: 2 green is a very important color -DEPRECATED!! - true +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.0 GB +.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 +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 +latest: 1.0.0 ` exports[`test/lib/commands/view.js TAP workspaces remote package name > must match snapshot 1`] = ` -pink@1.0.0 | Proprietary | deps: none | versions: 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 +latest: 1.0.0 ` 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)", - ], + "\\u001b[94mIgnoring workspaces for specified package(s)\\u001b[39m", ] ` diff --git a/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs b/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs index 64dad96903ec32..5ae16bc2d2c729 100644 --- a/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs @@ -2552,7 +2552,7 @@ exports[`test/lib/docs.js TAP usage access > must match snapshot 1`] = ` Set access level on published packages Usage: -npm access list packages [|| [] +npm access list packages [||] [] npm access list collaborators [ []] npm access get status [] npm access set status=public|private [] @@ -2566,7 +2566,7 @@ Options: Run "npm help access" for more info \`\`\`bash -npm access list packages [|| [] +npm access list packages [||] [] npm access list collaborators [ []] npm access get status [] npm access set status=public|private [] @@ -2958,7 +2958,7 @@ exports[`test/lib/docs.js TAP usage doctor > must match snapshot 1`] = ` Check the health of your npm environment Usage: -npm doctor [ping] [registry] [versions] [environment] [permissions] [cache] +npm doctor [connection] [registry] [versions] [environment] [permissions] [cache] Options: [--registry ] @@ -2966,7 +2966,7 @@ Options: Run "npm help doctor" for more info \`\`\`bash -npm doctor [ping] [registry] [versions] [environment] [permissions] [cache] +npm doctor [connection] [registry] [versions] [environment] [permissions] [cache] \`\`\` Note: This command is unaware of workspaces. @@ -4065,11 +4065,11 @@ exports[`test/lib/docs.js TAP usage search > must match snapshot 1`] = ` Search for packages Usage: -npm search [search terms ...] +npm search [ ...] Options: -[-l|--long] [--json] [--color|--no-color|--color always] [-p|--parseable] -[--no-description] [--searchlimit ] [--searchopts ] +[--json] [--color|--no-color|--color always] [-p|--parseable] [--no-description] +[--searchlimit ] [--searchopts ] [--searchexclude ] [--registry ] [--prefer-online] [--prefer-offline] [--offline] @@ -4078,14 +4078,13 @@ aliases: find, s, se Run "npm help search" for more info \`\`\`bash -npm search [search terms ...] +npm search [ ...] aliases: find, s, se \`\`\` Note: This command is unaware of workspaces. -#### \`long\` #### \`json\` #### \`color\` #### \`parseable\` diff --git a/deps/npm/tap-snapshots/test/lib/npm.js.test.cjs b/deps/npm/tap-snapshots/test/lib/npm.js.test.cjs index e29061291137eb..32ab47ef06b18e 100644 --- a/deps/npm/tap-snapshots/test/lib/npm.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/npm.js.test.cjs @@ -5,6 +5,16 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' +exports[`test/lib/npm.js TAP npm.load workspace-aware configs and commands > should exec workspaces version of commands 1`] = ` +Lifecycle scripts included in a@1.0.0: + test + echo test a + +Lifecycle scripts included in b@1.0.0: + test + echo test b +` + exports[`test/lib/npm.js TAP usage set process.stdout.columns column width 0 > must match snapshot 1`] = ` npm diff --git a/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs index fe581fb6beb291..e2301a60386582 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs @@ -190,7 +190,7 @@ Object { "r", "g", "s", - "https://evil:***@npmjs.org/", + "https://evil:***@npmjs.org", ], Array [ "", @@ -519,22 +519,10 @@ Object { exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":false,"loaded":true,"cachePath":false,"cacheDest":false} > must match snapshot 2`] = ` Array [ - Array [ - "title", - "npm", - ], - Array [ - "argv", - "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"", - ], - Array [ - "logfile", - "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", - ], - Array [ - "logfile", - "{CWD}/cache/_logs/{DATE}-debug-0.log", - ], + "title npm", + "argv /"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/" /"--loglevel/" /"silly/" /"--color/" /"false/"", + "logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", + "logfile {CWD}/cache/_logs/{DATE}-debug-0.log", ] ` @@ -559,22 +547,11 @@ Object { exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":false,"loaded":true,"cachePath":false,"cacheDest":true} > must match snapshot 2`] = ` Array [ - Array [ - "title", - "npm", - ], - Array [ - "argv", - "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"", - ], - Array [ - "logfile", - "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", - ], - Array [ - "logfile", - "{CWD}/cache/_logs/{DATE}-debug-0.log", - ], + "title npm", + "argv /"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/" /"--loglevel/" /"silly/" /"--color/" /"false/"", + "logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", + "logfile {CWD}/cache/_logs/{DATE}-debug-0.log", + "dummy stack trace", ] ` @@ -599,22 +576,11 @@ Object { exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":false,"loaded":true,"cachePath":true,"cacheDest":false} > must match snapshot 2`] = ` Array [ - Array [ - "title", - "npm", - ], - Array [ - "argv", - "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"", - ], - Array [ - "logfile", - "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", - ], - Array [ - "logfile", - "{CWD}/cache/_logs/{DATE}-debug-0.log", - ], + "title npm", + "argv /"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/" /"--loglevel/" /"silly/" /"--color/" /"false/"", + "logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", + "logfile {CWD}/cache/_logs/{DATE}-debug-0.log", + "dummy stack trace", ] ` @@ -639,22 +605,11 @@ Object { exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":false,"loaded":true,"cachePath":true,"cacheDest":true} > must match snapshot 2`] = ` Array [ - Array [ - "title", - "npm", - ], - Array [ - "argv", - "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"", - ], - Array [ - "logfile", - "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", - ], - Array [ - "logfile", - "{CWD}/cache/_logs/{DATE}-debug-0.log", - ], + "title npm", + "argv /"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/" /"--loglevel/" /"silly/" /"--color/" /"false/"", + "logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", + "logfile {CWD}/cache/_logs/{DATE}-debug-0.log", + "dummy stack trace", ] ` @@ -826,22 +781,10 @@ Object { exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":true,"loaded":true,"cachePath":false,"cacheDest":false} > must match snapshot 2`] = ` Array [ - Array [ - "title", - "npm", - ], - Array [ - "argv", - "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"", - ], - Array [ - "logfile", - "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", - ], - Array [ - "logfile", - "{CWD}/cache/_logs/{DATE}-debug-0.log", - ], + "title npm", + "argv /"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/" /"--loglevel/" /"silly/" /"--color/" /"false/"", + "logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", + "logfile {CWD}/cache/_logs/{DATE}-debug-0.log", ] ` @@ -877,22 +820,10 @@ Object { exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":true,"loaded":true,"cachePath":false,"cacheDest":true} > must match snapshot 2`] = ` Array [ - Array [ - "title", - "npm", - ], - Array [ - "argv", - "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"", - ], - Array [ - "logfile", - "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", - ], - Array [ - "logfile", - "{CWD}/cache/_logs/{DATE}-debug-0.log", - ], + "title npm", + "argv /"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/" /"--loglevel/" /"silly/" /"--color/" /"false/"", + "logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", + "logfile {CWD}/cache/_logs/{DATE}-debug-0.log", ] ` @@ -928,22 +859,10 @@ Object { exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":true,"loaded":true,"cachePath":true,"cacheDest":false} > must match snapshot 2`] = ` Array [ - Array [ - "title", - "npm", - ], - Array [ - "argv", - "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"", - ], - Array [ - "logfile", - "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", - ], - Array [ - "logfile", - "{CWD}/cache/_logs/{DATE}-debug-0.log", - ], + "title npm", + "argv /"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/" /"--loglevel/" /"silly/" /"--color/" /"false/"", + "logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", + "logfile {CWD}/cache/_logs/{DATE}-debug-0.log", ] ` @@ -979,22 +898,10 @@ Object { exports[`test/lib/utils/error-message.js TAP eacces/eperm {"windows":true,"loaded":true,"cachePath":true,"cacheDest":true} > must match snapshot 2`] = ` Array [ - Array [ - "title", - "npm", - ], - Array [ - "argv", - "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"", - ], - Array [ - "logfile", - "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", - ], - Array [ - "logfile", - "{CWD}/cache/_logs/{DATE}-debug-0.log", - ], + "title npm", + "argv /"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/" /"--loglevel/" /"silly/" /"--color/" /"false/"", + "logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}-", + "logfile {CWD}/cache/_logs/{DATE}-debug-0.log", ] ` diff --git a/deps/npm/tap-snapshots/test/lib/utils/explain-dep.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/explain-dep.js.test.cjs index 876cc6552b7605..34620d5c749bc0 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/explain-dep.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/explain-dep.js.test.cjs @@ -22,9 +22,9 @@ manydep@1.0.0 ` exports[`test/lib/utils/explain-dep.js TAP basic bundled > explain color deep 1`] = ` -bundle-of-joy@1.0.0 bundled +bundle-of-joy@1.0.0 bundled node_modules/bundle-of-joy - bundled prod-dep@"1.x" from the root project + bundled prod-dep@"1.x" from the root project ` exports[`test/lib/utils/explain-dep.js TAP basic bundled > explain nocolor shallow 1`] = ` @@ -34,7 +34,7 @@ node_modules/bundle-of-joy ` exports[`test/lib/utils/explain-dep.js TAP basic bundled > print color 1`] = ` -bundle-of-joy@1.0.0 bundled +bundle-of-joy@1.0.0 bundled node_modules/bundle-of-joy ` @@ -44,13 +44,13 @@ node_modules/bundle-of-joy ` exports[`test/lib/utils/explain-dep.js TAP basic deepDev > explain color deep 1`] = ` -deep-dev@2.3.4 dev +deep-dev@2.3.4 dev node_modules/deep-dev - deep-dev@"2.x" from metadev@3.4.5 + deep-dev@"2.x" from metadev@3.4.5 node_modules/dev/node_modules/metadev - metadev@"3.x" from topdev@4.5.6 + metadev@"3.x" from topdev@4.5.6 node_modules/topdev - dev topdev@"4.x" from the root project + dev topdev@"4.x" from the root project ` exports[`test/lib/utils/explain-dep.js TAP basic deepDev > explain nocolor shallow 1`] = ` @@ -63,7 +63,7 @@ node_modules/deep-dev ` exports[`test/lib/utils/explain-dep.js TAP basic deepDev > print color 1`] = ` -deep-dev@2.3.4 dev +deep-dev@2.3.4 dev node_modules/deep-dev ` @@ -73,7 +73,7 @@ node_modules/deep-dev ` exports[`test/lib/utils/explain-dep.js TAP basic extraneous > explain color deep 1`] = ` -extra-neos@1337.420.69-lol extraneous +extra-neos@1337.420.69-lol extraneous node_modules/extra-neos ` @@ -83,7 +83,7 @@ node_modules/extra-neos ` exports[`test/lib/utils/explain-dep.js TAP basic extraneous > print color 1`] = ` -extra-neos@1337.420.69-lol extraneous +extra-neos@1337.420.69-lol extraneous node_modules/extra-neos ` @@ -93,29 +93,29 @@ node_modules/extra-neos ` exports[`test/lib/utils/explain-dep.js TAP basic manyDeps > explain color deep 1`] = ` -manydep@1.0.0 - manydep@"1.0.0" from prod-dep@1.2.3 +manydep@1.0.0 + manydep@"1.0.0" from prod-dep@1.2.3 node_modules/prod-dep - prod-dep@"1.x" from the root project - optional manydep@"1.x" from optdep@1.0.0 optional + prod-dep@"1.x" from the root project + optional manydep@"1.x" from optdep@1.0.0 optional node_modules/optdep - optional optdep@"1.0.0" from the root project - manydep@"1.0.x" from extra-neos@1337.420.69-lol extraneous + optional optdep@"1.0.0" from the root project + manydep@"1.0.x" from extra-neos@1337.420.69-lol extraneous node_modules/extra-neos - dev manydep@"*" from deep-dev@2.3.4 dev + dev manydep@"*" from deep-dev@2.3.4 dev node_modules/deep-dev - deep-dev@"2.x" from metadev@3.4.5 + deep-dev@"2.x" from metadev@3.4.5 node_modules/dev/node_modules/metadev - metadev@"3.x" from topdev@4.5.6 + metadev@"3.x" from topdev@4.5.6 node_modules/topdev - dev topdev@"4.x" from the root project - peer manydep@">1.0.0-beta <1.0.1" from peer@1.0.0 peer + dev topdev@"4.x" from the root project + peer manydep@">1.0.0-beta <1.0.1" from peer@1.0.0 peer node_modules/peer - peer peer@"1.0.0" from the root project - manydep@">1.0.0-beta <1.0.1" from the root project - manydep@"1" from a package with a pretty long name@1.2.3 - manydep@"1" from another package with a pretty long name@1.2.3 - manydep@"1" from yet another a package with a pretty long name@1.2.3 + peer peer@"1.0.0" from the root project + manydep@">1.0.0-beta <1.0.1" from the root project + manydep@"1" from a package with a pretty long name@1.2.3 + manydep@"1" from another package with a pretty long name@1.2.3 + manydep@"1" from yet another a package with a pretty long name@1.2.3 ` exports[`test/lib/utils/explain-dep.js TAP basic manyDeps > explain nocolor shallow 1`] = ` @@ -127,7 +127,7 @@ manydep@1.0.0 ` exports[`test/lib/utils/explain-dep.js TAP basic manyDeps > print color 1`] = ` -manydep@1.0.0 +manydep@1.0.0 ` exports[`test/lib/utils/explain-dep.js TAP basic manyDeps > print nocolor 1`] = ` @@ -135,9 +135,9 @@ manydep@1.0.0 ` exports[`test/lib/utils/explain-dep.js TAP basic optional > explain color deep 1`] = ` -optdep@1.0.0 optional +optdep@1.0.0 optional node_modules/optdep - optional optdep@"1.0.0" from the root project + optional optdep@"1.0.0" from the root project ` exports[`test/lib/utils/explain-dep.js TAP basic optional > explain nocolor shallow 1`] = ` @@ -147,7 +147,7 @@ node_modules/optdep ` exports[`test/lib/utils/explain-dep.js TAP basic optional > print color 1`] = ` -optdep@1.0.0 optional +optdep@1.0.0 optional node_modules/optdep ` @@ -157,9 +157,9 @@ node_modules/optdep ` exports[`test/lib/utils/explain-dep.js TAP basic overridden > explain color deep 1`] = ` -overridden-root@1.0.0 overridden +overridden-root@1.0.0 overridden node_modules/overridden-root - overridden overridden-dep@"1.0.0" (was "^2.0.0") from the root project + overridden overridden-dep@"1.0.0" (was "^2.0.0") from the root project ` exports[`test/lib/utils/explain-dep.js TAP basic overridden > explain nocolor shallow 1`] = ` @@ -169,7 +169,7 @@ node_modules/overridden-root ` exports[`test/lib/utils/explain-dep.js TAP basic overridden > print color 1`] = ` -overridden-root@1.0.0 overridden +overridden-root@1.0.0 overridden node_modules/overridden-root ` @@ -179,9 +179,9 @@ node_modules/overridden-root ` exports[`test/lib/utils/explain-dep.js TAP basic peer > explain color deep 1`] = ` -peer@1.0.0 peer +peer@1.0.0 peer node_modules/peer - peer peer@"1.0.0" from the root project + peer peer@"1.0.0" from the root project ` exports[`test/lib/utils/explain-dep.js TAP basic peer > explain nocolor shallow 1`] = ` @@ -191,7 +191,7 @@ node_modules/peer ` exports[`test/lib/utils/explain-dep.js TAP basic peer > print color 1`] = ` -peer@1.0.0 peer +peer@1.0.0 peer node_modules/peer ` @@ -201,9 +201,9 @@ node_modules/peer ` exports[`test/lib/utils/explain-dep.js TAP basic prodDep > explain color deep 1`] = ` -prod-dep@1.2.3 +prod-dep@1.2.3 node_modules/prod-dep - prod-dep@"1.x" from the root project + prod-dep@"1.x" from the root project ` exports[`test/lib/utils/explain-dep.js TAP basic prodDep > explain nocolor shallow 1`] = ` @@ -213,7 +213,7 @@ node_modules/prod-dep ` exports[`test/lib/utils/explain-dep.js TAP basic prodDep > print color 1`] = ` -prod-dep@1.2.3 +prod-dep@1.2.3 node_modules/prod-dep ` @@ -223,11 +223,11 @@ node_modules/prod-dep ` exports[`test/lib/utils/explain-dep.js TAP basic workspaces > explain color deep 1`] = ` -a@1.0.0 +a@1.0.0 a - a@1.0.0 + a@1.0.0 node_modules/a - workspace a from the root project + workspace a from the root project ` exports[`test/lib/utils/explain-dep.js TAP basic workspaces > explain nocolor shallow 1`] = ` @@ -239,7 +239,7 @@ a ` exports[`test/lib/utils/explain-dep.js TAP basic workspaces > print color 1`] = ` -a@1.0.0 +a@1.0.0 a ` diff --git a/deps/npm/tap-snapshots/test/lib/utils/explain-eresolve.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/explain-eresolve.js.test.cjs index 3d73019d3e45b9..5190ead244697c 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/explain-eresolve.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/explain-eresolve.js.test.cjs @@ -6,15 +6,15 @@ */ 'use strict' exports[`test/lib/utils/explain-eresolve.js TAP basic chain-conflict > explain with color, depth of 2 1`] = ` -While resolving: project@1.2.3 -Found: @isaacs/testing-peer-dep-conflict-chain-d@2.0.0 +While resolving: project@1.2.3 +Found: @isaacs/testing-peer-dep-conflict-chain-d@2.0.0 node_modules/@isaacs/testing-peer-dep-conflict-chain-d - @isaacs/testing-peer-dep-conflict-chain-d@"2" from the root project + @isaacs/testing-peer-dep-conflict-chain-d@"2" from the root project Could not resolve dependency: -peer @isaacs/testing-peer-dep-conflict-chain-d@"1" from @isaacs/testing-peer-dep-conflict-chain-c@1.0.0 +peer @isaacs/testing-peer-dep-conflict-chain-d@"1" from @isaacs/testing-peer-dep-conflict-chain-c@1.0.0 node_modules/@isaacs/testing-peer-dep-conflict-chain-c - @isaacs/testing-peer-dep-conflict-chain-c@"1" from the root project + @isaacs/testing-peer-dep-conflict-chain-c@"1" from the root project ` exports[`test/lib/utils/explain-eresolve.js TAP basic chain-conflict > explain with no color, depth of 6 1`] = ` @@ -48,15 +48,15 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic chain-conflict > report with color 1`] = ` -While resolving: project@1.2.3 -Found: @isaacs/testing-peer-dep-conflict-chain-d@2.0.0 +While resolving: project@1.2.3 +Found: @isaacs/testing-peer-dep-conflict-chain-d@2.0.0 node_modules/@isaacs/testing-peer-dep-conflict-chain-d - @isaacs/testing-peer-dep-conflict-chain-d@"2" from the root project + @isaacs/testing-peer-dep-conflict-chain-d@"2" from the root project Could not resolve dependency: -peer @isaacs/testing-peer-dep-conflict-chain-d@"1" from @isaacs/testing-peer-dep-conflict-chain-c@1.0.0 +peer @isaacs/testing-peer-dep-conflict-chain-d@"1" from @isaacs/testing-peer-dep-conflict-chain-c@1.0.0 node_modules/@isaacs/testing-peer-dep-conflict-chain-c - @isaacs/testing-peer-dep-conflict-chain-c@"1" from the root project + @isaacs/testing-peer-dep-conflict-chain-c@"1" from the root project Fix the upstream dependency conflict, or retry this command with --force or --legacy-peer-deps @@ -80,20 +80,20 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic cycleNested > explain with color, depth of 2 1`] = ` -Found: @isaacs/peer-dep-cycle-c@2.0.0 +Found: @isaacs/peer-dep-cycle-c@2.0.0 node_modules/@isaacs/peer-dep-cycle-c - @isaacs/peer-dep-cycle-c@"2.x" from the root project + @isaacs/peer-dep-cycle-c@"2.x" from the root project Could not resolve dependency: -peer @isaacs/peer-dep-cycle-b@"1" from @isaacs/peer-dep-cycle-a@1.0.0 +peer @isaacs/peer-dep-cycle-b@"1" from @isaacs/peer-dep-cycle-a@1.0.0 node_modules/@isaacs/peer-dep-cycle-a - @isaacs/peer-dep-cycle-a@"1.x" from the root project + @isaacs/peer-dep-cycle-a@"1.x" from the root project -Conflicting peer dependency: @isaacs/peer-dep-cycle-c@1.0.0 +Conflicting peer dependency: @isaacs/peer-dep-cycle-c@1.0.0 node_modules/@isaacs/peer-dep-cycle-c - peer @isaacs/peer-dep-cycle-c@"1" from @isaacs/peer-dep-cycle-b@1.0.0 + peer @isaacs/peer-dep-cycle-c@"1" from @isaacs/peer-dep-cycle-b@1.0.0 node_modules/@isaacs/peer-dep-cycle-b - peer @isaacs/peer-dep-cycle-b@"1" from @isaacs/peer-dep-cycle-a@1.0.0 + peer @isaacs/peer-dep-cycle-b@"1" from @isaacs/peer-dep-cycle-a@1.0.0 node_modules/@isaacs/peer-dep-cycle-a ` @@ -142,22 +142,22 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic cycleNested > report with color 1`] = ` -Found: @isaacs/peer-dep-cycle-c@2.0.0 +Found: @isaacs/peer-dep-cycle-c@2.0.0 node_modules/@isaacs/peer-dep-cycle-c - @isaacs/peer-dep-cycle-c@"2.x" from the root project + @isaacs/peer-dep-cycle-c@"2.x" from the root project Could not resolve dependency: -peer @isaacs/peer-dep-cycle-b@"1" from @isaacs/peer-dep-cycle-a@1.0.0 +peer @isaacs/peer-dep-cycle-b@"1" from @isaacs/peer-dep-cycle-a@1.0.0 node_modules/@isaacs/peer-dep-cycle-a - @isaacs/peer-dep-cycle-a@"1.x" from the root project + @isaacs/peer-dep-cycle-a@"1.x" from the root project -Conflicting peer dependency: @isaacs/peer-dep-cycle-c@1.0.0 +Conflicting peer dependency: @isaacs/peer-dep-cycle-c@1.0.0 node_modules/@isaacs/peer-dep-cycle-c - peer @isaacs/peer-dep-cycle-c@"1" from @isaacs/peer-dep-cycle-b@1.0.0 + peer @isaacs/peer-dep-cycle-c@"1" from @isaacs/peer-dep-cycle-b@1.0.0 node_modules/@isaacs/peer-dep-cycle-b - peer @isaacs/peer-dep-cycle-b@"1" from @isaacs/peer-dep-cycle-a@1.0.0 + peer @isaacs/peer-dep-cycle-b@"1" from @isaacs/peer-dep-cycle-a@1.0.0 node_modules/@isaacs/peer-dep-cycle-a - @isaacs/peer-dep-cycle-a@"1.x" from the root project + @isaacs/peer-dep-cycle-a@"1.x" from the root project Fix the upstream dependency conflict, or retry this command with --no-strict-peer-deps, --force, or --legacy-peer-deps @@ -188,20 +188,20 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic eslint-plugin case > explain with color, depth of 2 1`] = ` -While resolving: eslint-plugin-react@7.24.0 -Found: eslint@6.8.0 +While resolving: eslint-plugin-react@7.24.0 +Found: eslint@6.8.0 node_modules/eslint - dev eslint@"^3 || ^4 || ^5 || ^6 || ^7" from the root project + dev eslint@"^3 || ^4 || ^5 || ^6 || ^7" from the root project 3 more (@typescript-eslint/parser, ...) Could not resolve dependency: -dev eslint-plugin-eslint-plugin@"^3.1.0" from the root project +dev eslint-plugin-eslint-plugin@"^3.1.0" from the root project -Conflicting peer dependency: eslint@7.31.0 +Conflicting peer dependency: eslint@7.31.0 node_modules/eslint - peer eslint@"^7.0.0" from eslint-plugin-eslint-plugin@3.5.1 + peer eslint@"^7.0.0" from eslint-plugin-eslint-plugin@3.5.1 node_modules/eslint-plugin-eslint-plugin - dev eslint-plugin-eslint-plugin@"^3.1.0" from the root project + dev eslint-plugin-eslint-plugin@"^3.1.0" from the root project ` exports[`test/lib/utils/explain-eresolve.js TAP basic eslint-plugin case > explain with no color, depth of 6 1`] = ` @@ -262,23 +262,23 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic eslint-plugin case > report with color 1`] = ` -While resolving: eslint-plugin-react@7.24.0 -Found: eslint@6.8.0 +While resolving: eslint-plugin-react@7.24.0 +Found: eslint@6.8.0 node_modules/eslint - dev eslint@"^3 || ^4 || ^5 || ^6 || ^7" from the root project - peer eslint@"^5.0.0 || ^6.0.0" from @typescript-eslint/parser@2.34.0 + dev eslint@"^3 || ^4 || ^5 || ^6 || ^7" from the root project + peer eslint@"^5.0.0 || ^6.0.0" from @typescript-eslint/parser@2.34.0 node_modules/@typescript-eslint/parser - dev @typescript-eslint/parser@"^2.34.0" from the root project + dev @typescript-eslint/parser@"^2.34.0" from the root project 2 more (eslint-config-airbnb-base, eslint-plugin-import) Could not resolve dependency: -dev eslint-plugin-eslint-plugin@"^3.1.0" from the root project +dev eslint-plugin-eslint-plugin@"^3.1.0" from the root project -Conflicting peer dependency: eslint@7.31.0 +Conflicting peer dependency: eslint@7.31.0 node_modules/eslint - peer eslint@"^7.0.0" from eslint-plugin-eslint-plugin@3.5.1 + peer eslint@"^7.0.0" from eslint-plugin-eslint-plugin@3.5.1 node_modules/eslint-plugin-eslint-plugin - dev eslint-plugin-eslint-plugin@"^3.1.0" from the root project + dev eslint-plugin-eslint-plugin@"^3.1.0" from the root project Fix the upstream dependency conflict, or retry this command with --force or --legacy-peer-deps @@ -310,18 +310,18 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic gatsby > explain with color, depth of 2 1`] = ` -While resolving: gatsby-recipes@0.2.31 -Found: ink@3.0.0-7 +While resolving: gatsby-recipes@0.2.31 +Found: ink@3.0.0-7 node_modules/ink - dev ink@"next" from gatsby-recipes@0.2.31 + dev ink@"next" from gatsby-recipes@0.2.31 node_modules/gatsby-recipes - gatsby-recipes@"^0.2.31" from gatsby-cli@2.12.107 + gatsby-recipes@"^0.2.31" from gatsby-cli@2.12.107 node_modules/gatsby-cli Could not resolve dependency: -peer ink@">=2.0.0" from ink-box@1.0.0 +peer ink@">=2.0.0" from ink-box@1.0.0 node_modules/ink-box - ink-box@"^1.0.0" from gatsby-recipes@0.2.31 + ink-box@"^1.0.0" from gatsby-recipes@0.2.31 node_modules/gatsby-recipes ` @@ -380,25 +380,25 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic gatsby > report with color 1`] = ` -While resolving: gatsby-recipes@0.2.31 -Found: ink@3.0.0-7 +While resolving: gatsby-recipes@0.2.31 +Found: ink@3.0.0-7 node_modules/ink - dev ink@"next" from gatsby-recipes@0.2.31 + dev ink@"next" from gatsby-recipes@0.2.31 node_modules/gatsby-recipes - gatsby-recipes@"^0.2.31" from gatsby-cli@2.12.107 + gatsby-recipes@"^0.2.31" from gatsby-cli@2.12.107 node_modules/gatsby-cli - gatsby-cli@"^2.12.107" from gatsby@2.24.74 + gatsby-cli@"^2.12.107" from gatsby@2.24.74 node_modules/gatsby - gatsby@"" from the root project + gatsby@"" from the root project Could not resolve dependency: -peer ink@">=2.0.0" from ink-box@1.0.0 +peer ink@">=2.0.0" from ink-box@1.0.0 node_modules/ink-box - ink-box@"^1.0.0" from gatsby-recipes@0.2.31 + ink-box@"^1.0.0" from gatsby-recipes@0.2.31 node_modules/gatsby-recipes - gatsby-recipes@"^0.2.31" from gatsby-cli@2.12.107 + gatsby-recipes@"^0.2.31" from gatsby-cli@2.12.107 node_modules/gatsby-cli - gatsby-cli@"^2.12.107" from gatsby@2.24.74 + gatsby-cli@"^2.12.107" from gatsby@2.24.74 node_modules/gatsby Fix the upstream dependency conflict, or retry @@ -434,13 +434,13 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, but has current edge > explain with color, depth of 2 1`] = ` -While resolving: eslint@7.22.0 -Found: dev eslint@"file:." from the root project +While resolving: eslint@7.22.0 +Found: dev eslint@"file:." from the root project Could not resolve dependency: -peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 +peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 node_modules/eslint-plugin-jsdoc - dev eslint-plugin-jsdoc@"^22.1.0" from the root project + dev eslint-plugin-jsdoc@"^22.1.0" from the root project ` exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, but has current edge > explain with no color, depth of 6 1`] = ` @@ -470,13 +470,13 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, but has current edge > report with color 1`] = ` -While resolving: eslint@7.22.0 -Found: dev eslint@"file:." from the root project +While resolving: eslint@7.22.0 +Found: dev eslint@"file:." from the root project Could not resolve dependency: -peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 +peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 node_modules/eslint-plugin-jsdoc - dev eslint-plugin-jsdoc@"^22.1.0" from the root project + dev eslint-plugin-jsdoc@"^22.1.0" from the root project Fix the upstream dependency conflict, or retry this command with --force or --legacy-peer-deps @@ -498,15 +498,15 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, no current edge, idk > explain with color, depth of 2 1`] = ` -While resolving: eslint@7.22.0 -Found: peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 +While resolving: eslint@7.22.0 +Found: peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 node_modules/eslint-plugin-jsdoc - dev eslint-plugin-jsdoc@"^22.1.0" from the root project + dev eslint-plugin-jsdoc@"^22.1.0" from the root project Could not resolve dependency: -peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 +peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 node_modules/eslint-plugin-jsdoc - dev eslint-plugin-jsdoc@"^22.1.0" from the root project + dev eslint-plugin-jsdoc@"^22.1.0" from the root project ` exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, no current edge, idk > explain with no color, depth of 6 1`] = ` @@ -540,15 +540,15 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic no current node, no current edge, idk > report with color 1`] = ` -While resolving: eslint@7.22.0 -Found: peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 +While resolving: eslint@7.22.0 +Found: peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 node_modules/eslint-plugin-jsdoc - dev eslint-plugin-jsdoc@"^22.1.0" from the root project + dev eslint-plugin-jsdoc@"^22.1.0" from the root project Could not resolve dependency: -peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 +peer eslint@"^6.0.0" from eslint-plugin-jsdoc@22.2.0 node_modules/eslint-plugin-jsdoc - dev eslint-plugin-jsdoc@"^22.1.0" from the root project + dev eslint-plugin-jsdoc@"^22.1.0" from the root project Fix the upstream dependency conflict, or retry this command with --force or --legacy-peer-deps @@ -572,15 +572,15 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic withShrinkwrap > explain with color, depth of 2 1`] = ` -While resolving: @isaacs/peer-dep-cycle-b@1.0.0 -Found: @isaacs/peer-dep-cycle-c@2.0.0 +While resolving: @isaacs/peer-dep-cycle-b@1.0.0 +Found: @isaacs/peer-dep-cycle-c@2.0.0 node_modules/@isaacs/peer-dep-cycle-c - @isaacs/peer-dep-cycle-c@"2.x" from the root project + @isaacs/peer-dep-cycle-c@"2.x" from the root project Could not resolve dependency: -peer @isaacs/peer-dep-cycle-c@"1" from @isaacs/peer-dep-cycle-b@1.0.0 +peer @isaacs/peer-dep-cycle-c@"1" from @isaacs/peer-dep-cycle-b@1.0.0 node_modules/@isaacs/peer-dep-cycle-b - peer @isaacs/peer-dep-cycle-b@"1" from @isaacs/peer-dep-cycle-a@1.0.0 + peer @isaacs/peer-dep-cycle-b@"1" from @isaacs/peer-dep-cycle-a@1.0.0 node_modules/@isaacs/peer-dep-cycle-a ` @@ -619,17 +619,17 @@ to accept an incorrect (and potentially broken) dependency resolution. ` exports[`test/lib/utils/explain-eresolve.js TAP basic withShrinkwrap > report with color 1`] = ` -While resolving: @isaacs/peer-dep-cycle-b@1.0.0 -Found: @isaacs/peer-dep-cycle-c@2.0.0 +While resolving: @isaacs/peer-dep-cycle-b@1.0.0 +Found: @isaacs/peer-dep-cycle-c@2.0.0 node_modules/@isaacs/peer-dep-cycle-c - @isaacs/peer-dep-cycle-c@"2.x" from the root project + @isaacs/peer-dep-cycle-c@"2.x" from the root project Could not resolve dependency: -peer @isaacs/peer-dep-cycle-c@"1" from @isaacs/peer-dep-cycle-b@1.0.0 +peer @isaacs/peer-dep-cycle-c@"1" from @isaacs/peer-dep-cycle-b@1.0.0 node_modules/@isaacs/peer-dep-cycle-b - peer @isaacs/peer-dep-cycle-b@"1" from @isaacs/peer-dep-cycle-a@1.0.0 + peer @isaacs/peer-dep-cycle-b@"1" from @isaacs/peer-dep-cycle-a@1.0.0 node_modules/@isaacs/peer-dep-cycle-a - @isaacs/peer-dep-cycle-a@"1.x" from the root project + @isaacs/peer-dep-cycle-a@"1.x" from the root project Fix the upstream dependency conflict, or retry this command with --no-strict-peer-deps, --force, or --legacy-peer-deps diff --git a/deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs index 0a4af7cadf0607..34002b8133e229 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs @@ -7,64 +7,65 @@ 'use strict' exports[`test/lib/utils/log-file.js TAP snapshot > must match snapshot 1`] = ` 0 verbose logfile logs-max:10 dir:{CWD}/{DATE}- -1 silly logfile done cleaning log files -2 error no prefix -3 error prefix with prefix -4 error prefix 1 2 3 -5 verbose { obj: { with: { many: [Object] } } } -6 verbose {"obj":{"with":{"many":{"props":1}}}} -7 verbose { -7 verbose "obj": { -7 verbose "with": { -7 verbose "many": { -7 verbose "props": 1 -7 verbose } -7 verbose } -7 verbose } -7 verbose } -8 verbose [ 'test', 'with', 'an', 'array' ] -9 verbose ["test","with","an","array"] -10 verbose [ -10 verbose "test", -10 verbose "with", -10 verbose "an", -10 verbose "array" -10 verbose ] -11 verbose [ 'test', [ 'with', [ 'an', [Array] ] ] ] -12 verbose ["test",["with",["an",["array"]]]] -13 verbose [ -13 verbose "test", -13 verbose [ -13 verbose "with", -13 verbose [ -13 verbose "an", -13 verbose [ -13 verbose "array" -13 verbose ] -13 verbose ] -13 verbose ] -13 verbose ] -14 error pre has many errors Error: message -14 error pre at stack trace line 0 -14 error pre at stack trace line 1 -14 error pre at stack trace line 2 -14 error pre at stack trace line 3 -14 error pre at stack trace line 4 -14 error pre at stack trace line 5 -14 error pre at stack trace line 6 -14 error pre at stack trace line 7 -14 error pre at stack trace line 8 -14 error pre at stack trace line 9 Error: message2 -14 error pre at stack trace line 0 -14 error pre at stack trace line 1 -14 error pre at stack trace line 2 -14 error pre at stack trace line 3 -14 error pre at stack trace line 4 -14 error pre at stack trace line 5 -14 error pre at stack trace line 6 -14 error pre at stack trace line 7 -14 error pre at stack trace line 8 -14 error pre at stack trace line 9 -15 error nostack [Error: message] +1 verbose logfile {CWD}/{DATE}-debug-0.log +2 silly logfile done cleaning log files +3 error no prefix +4 error prefix with prefix +5 error prefix 1 2 3 +6 verbose { obj: { with: { many: [Object] } } } +7 verbose {"obj":{"with":{"many":{"props":1}}}} +8 verbose { +8 verbose "obj": { +8 verbose "with": { +8 verbose "many": { +8 verbose "props": 1 +8 verbose } +8 verbose } +8 verbose } +8 verbose } +9 verbose [ 'test', 'with', 'an', 'array' ] +10 verbose ["test","with","an","array"] +11 verbose [ +11 verbose "test", +11 verbose "with", +11 verbose "an", +11 verbose "array" +11 verbose ] +12 verbose [ 'test', [ 'with', [ 'an', [Array] ] ] ] +13 verbose ["test",["with",["an",["array"]]]] +14 verbose [ +14 verbose "test", +14 verbose [ +14 verbose "with", +14 verbose [ +14 verbose "an", +14 verbose [ +14 verbose "array" +14 verbose ] +14 verbose ] +14 verbose ] +14 verbose ] +15 error pre has many errors Error: message +15 error pre at stack trace line 0 +15 error pre at stack trace line 1 +15 error pre at stack trace line 2 +15 error pre at stack trace line 3 +15 error pre at stack trace line 4 +15 error pre at stack trace line 5 +15 error pre at stack trace line 6 +15 error pre at stack trace line 7 +15 error pre at stack trace line 8 +15 error pre at stack trace line 9 Error: message2 +15 error pre at stack trace line 0 +15 error pre at stack trace line 1 +15 error pre at stack trace line 2 +15 error pre at stack trace line 3 +15 error pre at stack trace line 4 +15 error pre at stack trace line 5 +15 error pre at stack trace line 6 +15 error pre at stack trace line 7 +15 error pre at stack trace line 8 +15 error pre at stack trace line 9 +16 error nostack [Error: message] ` diff --git a/deps/npm/tap-snapshots/test/lib/utils/open-url-prompt.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/open-url-prompt.js.test.cjs index f31ec8e041f517..cf5feed44cc373 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/open-url-prompt.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/open-url-prompt.js.test.cjs @@ -10,7 +10,6 @@ npm home: https://www.npmjs.com Browser unavailable. Please open the URL manually: https://www.npmjs.com - ` exports[`test/lib/utils/open-url-prompt.js TAP opens a url > must match snapshot 1`] = ` diff --git a/deps/npm/tap-snapshots/test/lib/utils/open-url.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/open-url.js.test.cjs index 8c8159ebcfc04c..f1560db686cde0 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/open-url.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/open-url.js.test.cjs @@ -8,7 +8,6 @@ exports[`test/lib/utils/open-url.js TAP prints where to go when browser is disabled > printed expected message 1`] = ` npm home: https://www.npmjs.com - ` exports[`test/lib/utils/open-url.js TAP prints where to go when browser is disabled and json is enabled > printed expected message 1`] = ` @@ -21,5 +20,4 @@ exports[`test/lib/utils/open-url.js TAP prints where to go when browser is disab exports[`test/lib/utils/open-url.js TAP prints where to go when given browser does not exist > printed expected message 1`] = ` npm home: https://www.npmjs.com - ` diff --git a/deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs index 3e3df9039efb91..d653d4c1fadc0d 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs @@ -1634,19 +1634,17 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added" ` exports[`test/lib/utils/reify-output.js TAP prints dedupe difference on dry-run > diff table 1`] = ` - -change bar 1.0.0 -> 2.1.0 -remove bar 1.0.0 -add foo 1.0.0 +change bar 1.0.0 => 2.1.0 +remove bar 1.0.0 +add foo 1.0.0 removed 1 package, and changed 1 package in {TIME} ` exports[`test/lib/utils/reify-output.js TAP prints dedupe difference on long > diff table 1`] = ` - -change bar 1.0.0 -> 2.1.0 -remove bar 1.0.0 -add foo 1.0.0 +change bar 1.0.0 => 2.1.0 +remove bar 1.0.0 +add foo 1.0.0 removed 1 package, and changed 1 package in {TIME} ` diff --git a/deps/npm/tap-snapshots/test/lib/utils/tar.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/tar.js.test.cjs index e92314b57025eb..fda9577c843901 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/tar.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/tar.js.test.cjs @@ -9,28 +9,38 @@ exports[`test/lib/utils/tar.js TAP should log tarball contents > must match snap package: my-cool-pkg@1.0.0 -=== Tarball Contents === +Tarball Contents -4B cat -4B chai -4B dog +4B cat +4B chai +4B dog 114B package.json -=== Bundled Dependencies === +Bundled Dependencies bundle-dep -=== Tarball Details === +Tarball Details + +name: my-cool-pkg + +version: 1.0.0 + +filename: my-cool-pkg-1.0.0.tgz + +package size: {size} -name: my-cool-pkg -version: 1.0.0 -filename: my-cool-pkg-1.0.0.tgz -package size: {size} unpacked size: 126 B -shasum: {sha} -integrity: {integrity} -bundled deps: 1 + +shasum: {sha} + +integrity: {integrity} + +bundled deps: 1 + bundled files: 0 -own files: 5 -total files: 5 + +own files: 5 + +total files: 5 ` @@ -39,28 +49,38 @@ exports[`test/lib/utils/tar.js TAP should log tarball contents of a scoped packa package: @myscope/my-cool-pkg@1.0.0 -=== Tarball Contents === +Tarball Contents -4B cat -4B chai -4B dog +4B cat +4B chai +4B dog 123B package.json -=== Bundled Dependencies === +Bundled Dependencies bundle-dep -=== Tarball Details === +Tarball Details + +name: @myscope/my-cool-pkg + +version: 1.0.0 + +filename: myscope-my-cool-pkg-1.0.0.tgz + +package size: {size} -name: @myscope/my-cool-pkg -version: 1.0.0 -filename: myscope-my-cool-pkg-1.0.0.tgz -package size: {size} unpacked size: 135 B -shasum: {sha} -integrity: {integrity} -bundled deps: 1 -bundled files: 0 -own files: 5 -total files: 5 + +shasum: {sha} + +integrity: {integrity} + +bundled deps: 1 + +bundled files: 0 + +own files: 5 + +total files: 5 ` diff --git a/deps/npm/tap-snapshots/test/lib/utils/update-notifier.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/update-notifier.js.test.cjs deleted file mode 100644 index e5e9dd77569e00..00000000000000 --- a/deps/npm/tap-snapshots/test/lib/utils/update-notifier.js.test.cjs +++ /dev/null @@ -1,102 +0,0 @@ -/* IMPORTANT - * This snapshot file is auto-generated, but designed for humans. - * It should be checked into source control and tracked carefully. - * Re-generate by setting TAP_SNAPSHOT=1 and running tests. - * Make sure to inspect the output below. Do not ignore changes! - */ -'use strict' -exports[`test/lib/utils/update-notifier.js TAP notification situations 122.420.69 - color=always > must match snapshot 1`] = ` - -New major version of npm available! 122.420.69 -> 123.420.69 -Changelog: https://github.com/npm/cli/releases/tag/v123.420.69 -Run npm install -g npm@123.420.69 to update! - -` - -exports[`test/lib/utils/update-notifier.js TAP notification situations 122.420.69 - color=false > must match snapshot 1`] = ` - -New major version of npm available! 122.420.69 -> 123.420.69 -Changelog: -Run \`npm install -g npm@123.420.69\` to update! - -` - -exports[`test/lib/utils/update-notifier.js TAP notification situations 123.419.69 - color=always > must match snapshot 1`] = ` - -New minor version of npm available! 123.419.69 -> 123.420.69 -Changelog: https://github.com/npm/cli/releases/tag/v123.420.69 -Run npm install -g npm@123.420.69 to update! - -` - -exports[`test/lib/utils/update-notifier.js TAP notification situations 123.419.69 - color=false > must match snapshot 1`] = ` - -New minor version of npm available! 123.419.69 -> 123.420.69 -Changelog: -Run \`npm install -g npm@123.420.69\` to update! - -` - -exports[`test/lib/utils/update-notifier.js TAP notification situations 123.420.68 - color=always > must match snapshot 1`] = ` - -New patch version of npm available! 123.420.68 -> 123.420.69 -Changelog: https://github.com/npm/cli/releases/tag/v123.420.69 -Run npm install -g npm@123.420.69 to update! - -` - -exports[`test/lib/utils/update-notifier.js TAP notification situations 123.420.68 - color=false > must match snapshot 1`] = ` - -New patch version of npm available! 123.420.68 -> 123.420.69 -Changelog: -Run \`npm install -g npm@123.420.69\` to update! - -` - -exports[`test/lib/utils/update-notifier.js TAP notification situations 123.420.70 - color=always > must match snapshot 1`] = ` - -New minor version of npm available! 123.420.70 -> 123.421.70 -Changelog: https://github.com/npm/cli/releases/tag/v123.421.70 -Run npm install -g npm@123.421.70 to update! - -` - -exports[`test/lib/utils/update-notifier.js TAP notification situations 123.420.70 - color=false > must match snapshot 1`] = ` - -New minor version of npm available! 123.420.70 -> 123.421.70 -Changelog: -Run \`npm install -g npm@123.421.70\` to update! - -` - -exports[`test/lib/utils/update-notifier.js TAP notification situations 123.421.69 - color=always > must match snapshot 1`] = ` - -New patch version of npm available! 123.421.69 -> 123.421.70 -Changelog: https://github.com/npm/cli/releases/tag/v123.421.70 -Run npm install -g npm@123.421.70 to update! - -` - -exports[`test/lib/utils/update-notifier.js TAP notification situations 123.421.69 - color=false > must match snapshot 1`] = ` - -New patch version of npm available! 123.421.69 -> 123.421.70 -Changelog: -Run \`npm install -g npm@123.421.70\` to update! - -` - -exports[`test/lib/utils/update-notifier.js TAP notification situations 124.0.0-beta.0 - color=always > must match snapshot 1`] = ` - -New prerelease version of npm available! 124.0.0-beta.0 -> 124.0.0-beta.99999 -Changelog: https://github.com/npm/cli/releases/tag/v124.0.0-beta.99999 -Run npm install -g npm@124.0.0-beta.99999 to update! - -` - -exports[`test/lib/utils/update-notifier.js TAP notification situations 124.0.0-beta.0 - color=false > must match snapshot 1`] = ` - -New prerelease version of npm available! 124.0.0-beta.0 -> 124.0.0-beta.99999 -Changelog: -Run \`npm install -g npm@124.0.0-beta.99999\` to update! - -` diff --git a/deps/npm/test/bin/windows-shims.js b/deps/npm/test/bin/windows-shims.js index 2abe5013bf10bd..71f12dc8e1cdda 100644 --- a/deps/npm/test/bin/windows-shims.js +++ b/deps/npm/test/bin/windows-shims.js @@ -1,8 +1,9 @@ const t = require('tap') const { spawnSync } = require('child_process') -const { resolve, join, extname, basename, sep } = require('path') -const { copyFileSync, readFileSync, chmodSync, readdirSync, rmSync, statSync } = require('fs') +const { resolve, join, extname, basename } = require('path') +const { readFileSync, chmodSync, readdirSync, statSync } = require('fs') const Diff = require('diff') +const { moveRemove } = require('rimraf') const { sync: which } = require('which') const { version } = require('../../package.json') @@ -20,12 +21,6 @@ const SHIMS = readNonJsFiles(BIN) const NODE_GYP = readNonJsFiles(join(BIN, 'node-gyp-bin')) const SHIM_EXTS = [...new Set(Object.keys(SHIMS).map(p => extname(p)))] -// windows requires each segment of a command path to be quoted when using shell: true -const quotePath = (cmd) => cmd - .split(sep) - .map(p => p.includes(' ') ? `"${p}"` : p) - .join(sep) - t.test('shim contents', t => { // these scripts should be kept in sync so this tests the contents of each // and does a diff to ensure the only differences between them are necessary @@ -82,6 +77,7 @@ t.test('node-gyp', t => { t.test('run shims', t => { const path = t.testdir({ ...SHIMS, + 'node.exe': readFileSync(process.execPath), // simulate the state where one version of npm is installed // with node, but we should load the globally installed one 'global-prefix': { @@ -105,26 +101,23 @@ t.test('run shims', t => { }, }) - // hacky fix to decrease flakes of this test from `NOTEMPTY: directory not empty, rmdir` - // this should get better in tap@18 and we can try removing it then - copyFileSync(process.execPath, join(path, 'node.exe')) - t.teardown(async () => { - rmSync(join(path, 'node.exe')) - await new Promise(res => setTimeout(res, 100)) - // this is superstition - rmSync(join(path, 'node.exe'), { force: true }) - }) + // The removal of this fixture causes this test to fail when done with + // the default tap removal. Using rimraf's `moveRemove` seems to make this + // work reliably. Don't remove this line in the future without making sure + // this test passes the full windows suite at least 3 consecutive times. + t.teardown(() => moveRemove(join(path, 'node.exe'))) const spawnPath = (cmd, args, { log, stdioString = true, ...opts } = {}) => { if (cmd.endsWith('bash.exe')) { // only cygwin *requires* the -l, but the others are ok with it args.unshift('-l') } - const result = spawnSync(cmd, args, { + const result = spawnSync(`"${cmd}"`, args, { // don't hit the registry for the update check env: { PATH: path, npm_config_update_notifier: 'false' }, cwd: path, windowsHide: true, + shell: true, ...opts, }) if (stdioString) { @@ -235,9 +228,7 @@ t.test('run shims', t => { args.push(bin) break case 'pwsh.exe': - cmd = quotePath(cmd) args.push(`${bin}.ps1`) - opts.shell = true break default: throw new Error('unknown shell') diff --git a/deps/npm/test/fixtures/libnpmsearch-stream-result.js b/deps/npm/test/fixtures/libnpmsearch-stream-result.js index 68245beff6e46f..872a7940340d47 100644 --- a/deps/npm/test/fixtures/libnpmsearch-stream-result.js +++ b/deps/npm/test/fixtures/libnpmsearch-stream-result.js @@ -283,6 +283,7 @@ module.exports = [ scope: 'unscoped', version: '1.0.0', date: '2019-09-26T22:24:28.713Z', + publisher: { username: 'lukekarrys', email: 'lukekarrys' }, maintainers: [{ username: 'lukekarrys', email: 'lukekarrys' }], }, ] diff --git a/deps/npm/test/fixtures/mock-logs.js b/deps/npm/test/fixtures/mock-logs.js index c75de5e509463d..ce4c189219467d 100644 --- a/deps/npm/test/fixtures/mock-logs.js +++ b/deps/npm/test/fixtures/mock-logs.js @@ -1,131 +1,101 @@ +const { log: { LEVELS } } = require('proc-log') +const { stripVTControlCharacters: stripAnsi } = require('util') -const NPMLOG = require('npmlog') -const { LEVELS } = require('proc-log') +const logPrefix = new RegExp(`^npm (${LEVELS.join('|')})\\s`) +const isLog = (str) => logPrefix.test(stripAnsi(str)) -const npmEmitLog = NPMLOG.emitLog.bind(NPMLOG) -const npmLog = NPMLOG.log.bind(NPMLOG) +// We only strip trailing newlines since some output will +// have significant tabs and spaces +const trimTrailingNewline = (str) => str.replace(/\n$/, '') -const merge = (...objs) => objs.reduce((acc, obj) => ({ ...acc, ...obj })) +const joinAndTrimTrailingNewlines = (arr) => + trimTrailingNewline(arr.map(trimTrailingNewline).join('\n')) -const mockLogs = (otherMocks = {}) => { - // Return mocks as an array with getters for each level - // that return an array of logged properties with the - // level removed. This is for convenience throughout tests - const logs = Object.defineProperties( - [], - ['timing', ...LEVELS].reduce((acc, level) => { - acc[level] = { - get () { - return this - .filter(([l]) => level === l) - .map(([l, ...args]) => args) - }, - } - return acc - }, {}) - ) +const logsByTitle = (logs) => ({ + byTitle: { + value: (title) => { + return logs + .filter((l) => stripAnsi(l.message).startsWith(`${title} `)) + .map((l) => l.message) + }, + }, +}) - // the above logs array is anything logged and it not filtered by level. - // this display array is filtered and will not include items that - // would not be shown in the terminal - const display = Object.defineProperties( - [], - ['timing', ...LEVELS].reduce((acc, level) => { +module.exports = () => { + const outputs = [] + const outputErrors = [] + + const levelLogs = [] + const logs = Object.defineProperties([], { + ...logsByTitle(levelLogs), + ...LEVELS.reduce((acc, level) => { acc[level] = { get () { - return this - .filter(([l]) => level === l) - .map(([l, ...args]) => args) + const byLevel = levelLogs.filter((l) => l.level === level) + return Object.defineProperties(byLevel.map((l) => l.message), logsByTitle(byLevel)) }, } return acc - }, {}) - ) + }, {}), + }) - const npmLogBuffer = [] + const streams = { + stderr: { + cursorTo: () => {}, + clearLine: () => {}, + write: (str) => { + str = trimTrailingNewline(str) - // This returns an object with mocked versions of all necessary - // logging modules. It mocks them with methods that add logs - // to an array which it also returns. The reason it also returns - // the mocks is that in tests the same instance of these mocks - // should be passed to multiple calls to t.mock. - // XXX: this is messy and fragile and should be removed in favor - // of some other way to collect and filter logs across all tests - const logMocks = { - 'proc-log': merge( - { LEVELS }, - LEVELS.reduce((acc, l) => { - acc[l] = (...args) => { - // Re-emit log item for since the log file listens on these - process.emit('log', l, ...args) - // Dont add pause/resume events to the logs. Those aren't displayed - // and emitting them is tested in the display layer - if (l !== 'pause' && l !== 'resume') { - logs.push([l, ...args]) - } + // Use the beginning of each line to determine if its a log + // or an output error since we write both of those to stderr. + // This couples logging format to this test but we only need + // to do it in a single place so hopefully its easy to change + // in the future if/when we refactor what logs look like. + if (!isLog(str)) { + outputErrors.push(str) + return } - return acc - }, {}), - otherMocks['proc-log'] - ), - // Object.assign is important here because we need to assign - // mocked properties directly to npmlog and then mock with that - // object. This is necessary so tests can still directly set - // `log.level = 'silent'` anywhere in the test and have that - // that reflected in the npmlog singleton. - // XXX: remove with npmlog - npmlog: Object.assign(NPMLOG, merge( - { - log: (level, ...args) => { - // timing does not exist on proclog, so if it got logged - // with npmlog we need to push it to our logs - if (level === 'timing') { - logs.push([level, ...args]) - } - npmLog(level, ...args) - }, - write: (msg) => { - // npmlog.write is what outputs to the terminal. - // it writes in chunks so we push each chunk to an - // array that we will log and zero out - npmLogBuffer.push(msg) - }, - emitLog: (m) => { - // this calls the original emitLog method - // which will filter based on loglevel - npmEmitLog(m) - // if anything was logged then we push to our display - // array which we can assert against in tests - if (npmLogBuffer.length) { - // first two parts are 'npm' and a single space - display.push(npmLogBuffer.slice(2)) - } - npmLogBuffer.length = 0 - }, - newItem: () => { - return { - info: (...p) => { - logs.push(['info', ...p]) - }, - warn: (...p) => { - logs.push(['warn', ...p]) - }, - error: (...p) => { - logs.push(['error', ...p]) - }, - silly: (...p) => { - logs.push(['silly', ...p]) - }, - completeWork: () => {}, - finish: () => {}, - } - }, + + // Split on spaces for the heading and level/label. We know that + // none of those have spaces but could be colorized so there's no + // other good way to get each of those including control chars + const [rawHeading, rawLevel] = str.split(' ') + const rawPrefix = `${rawHeading} ${rawLevel} ` + // If message is colorized we can just replaceAll with the string since + // it will be unique due to control chars. Otherwise we create a regex + // that will only match the beginning of each line. + const prefix = stripAnsi(str) !== str ? rawPrefix : new RegExp(`^${rawPrefix}`, 'gm') + + // The level needs color stripped always because we use it to filter logs + const level = stripAnsi(rawLevel) + + logs.push(str.replaceAll(prefix, `${level} `)) + levelLogs.push({ level, message: str.replaceAll(prefix, '') }) + }, + }, + stdout: { + write: (str) => { + outputs.push(trimTrailingNewline(str)) }, - otherMocks.npmlog - )), + }, } - return { logs, logMocks, display } + return { + streams, + logs: { + outputs, + joinedOutput: () => joinAndTrimTrailingNewlines(outputs), + clearOutput: () => { + outputs.length = 0 + outputErrors.length = 0 + }, + outputErrors, + joinedOutputError: () => joinAndTrimTrailingNewlines(outputs), + logs, + clearLogs: () => { + levelLogs.length = 0 + logs.length = 0 + }, + }, + } } - -module.exports = mockLogs diff --git a/deps/npm/test/fixtures/mock-npm.js b/deps/npm/test/fixtures/mock-npm.js index 4646e79146e86e..d8a4834a9abfff 100644 --- a/deps/npm/test/fixtures/mock-npm.js +++ b/deps/npm/test/fixtures/mock-npm.js @@ -2,8 +2,9 @@ const os = require('os') const fs = require('fs').promises const path = require('path') const tap = require('tap') +const { output, META } = require('proc-log') const errorMessage = require('../../lib/utils/error-message') -const mockLogs = require('./mock-logs') +const mockLogs = require('./mock-logs.js') const mockGlobals = require('@npmcli/mock-globals') const tmock = require('./tmock') const defExitCode = process.exitCode @@ -48,29 +49,41 @@ const setGlobalNodeModules = (globalDir) => { } const buildMocks = (t, mocks) => { - const allMocks = { - '{LIB}/utils/update-notifier.js': async () => {}, - ...mocks, - } + const allMocks = { ...mocks } // The definitions must be mocked since they are a singleton that reads from // process and environs to build defaults in order to break the requiure // cache. We also need to mock them with any mocks that were passed in for the // test in case those mocks are for things like ci-info which is used there. const definitions = '@npmcli/config/lib/definitions' allMocks[definitions] = tmock(t, definitions, allMocks) - return allMocks } const getMockNpm = async (t, { mocks, init, load, npm: npmOpts }) => { - const { logMocks, logs, display } = mockLogs(mocks) - const allMocks = buildMocks(t, { ...mocks, ...logMocks }) + const { streams, logs } = mockLogs() + const allMocks = buildMocks(t, mocks) const Npm = tmock(t, '{LIB}/npm.js', allMocks) - const outputs = [] - const outputErrors = [] - class MockNpm extends Npm { + constructor (opts) { + super({ + ...opts, + ...streams, + ...npmOpts, + }) + } + + async load () { + const res = await super.load() + // Wait for any promises (currently only log file cleaning) to be + // done before returning from load in tests. This helps create more + // deterministic testing behavior because in reality that promise + // is left hanging on purpose as a best-effort and the process gets + // closed regardless of if it has finished or not. + await Promise.all(this.unrefPromises) + return res + } + async exec (...args) { const [res, err] = await super.exec(...args).then((r) => [r]).catch(e => [null, e]) // This mimics how the exit handler flushes output for commands that have @@ -78,32 +91,16 @@ const getMockNpm = async (t, { mocks, init, load, npm: npmOpts }) => { // error message fn. This is necessary for commands with buffered output // to read the output after exec is called. This is not *exactly* how it // works in practice, but it is close enough for now. - this.flushOutput(err ? errorMessage(err, this).json : null) + const jsonError = err && errorMessage(err, this).json + output.flush({ [META]: true, jsonError }) if (err) { throw err } return res } - - // lib/npm.js tests needs this to actually test the function! - originalOutput (...args) { - super.output(...args) - } - - originalOutputError (...args) { - super.outputError(...args) - } - - output (...args) { - outputs.push(args) - } - - outputError (...args) { - outputErrors.push(args) - } } - const npm = init ? new MockNpm(npmOpts) : null + const npm = init ? new MockNpm() : null if (npm && load) { await npm.load() } @@ -111,12 +108,7 @@ const getMockNpm = async (t, { mocks, init, load, npm: npmOpts }) => { return { Npm: MockNpm, npm, - outputs, - outputErrors, - joinedOutput: () => outputs.map(o => o.join(' ')).join('\n'), - logMocks, - logs, - display, + ...logs, } } @@ -128,7 +120,6 @@ const setupMockNpm = async (t, { // preload a command command = null, // string name of the command exec = null, // optionally exec the command before returning - setCmd = false, // test dirs prefixDir = {}, homeDir = {}, @@ -142,7 +133,6 @@ const setupMockNpm = async (t, { globals = {}, npm: npmOpts = {}, argv: rawArgv = [], - ...r } = {}) => { // easy to accidentally forget to pass in tap if (!(t instanceof tap.Test)) { @@ -213,6 +203,11 @@ const setupMockNpm = async (t, { // explicitly set in a test. 'fetch-retries': 0, cache: dirs.cache, + // This will give us all the loglevels including timing in a non-colorized way + // so we can easily assert their contents. Individual tests can overwrite these + // with my passing in configs if they need to test other forms of output. + loglevel: 'silly', + color: false, } const { argv, env, config } = Object.entries({ ...defaultConfigs, ...withDirs(_config) }) @@ -221,11 +216,13 @@ const setupMockNpm = async (t, { // and quoted with `"` so mock globals will ignore that it contains dots if (key.startsWith('//')) { acc.env[`process.env."npm_config_${key}"`] = value - } else { + } else if (value !== undefined) { const values = [].concat(value) - acc.argv.push(...values.flatMap(v => `--${key}=${v.toString()}`)) + acc.argv.push(...values.flatMap(v => v === '' ? `--${key}` : `--${key}=${v.toString()}`)) + } + if (value !== undefined) { + acc.config[key] = value } - acc.config[key] = value return acc }, { argv: [...rawArgv], env: {}, config: {} }) @@ -244,7 +241,11 @@ const setupMockNpm = async (t, { init, load, mocks: withDirs(mocks), - npm: { argv, excludeNpmCwd: true, ...withDirs(npmOpts) }, + npm: { + argv: command ? [command, ...argv] : argv, + excludeNpmCwd: true, + ...withDirs(npmOpts), + }, }) if (config.omit?.includes('prod')) { @@ -269,16 +270,6 @@ const setupMockNpm = async (t, { const mockCommand = {} if (command) { const Cmd = mockNpm.Npm.cmd(command) - if (setCmd) { - // XXX(hack): This is a hack to allow fake-ish tests to set the currently - // running npm command without running exec. Generally, we should rely on - // actually exec-ing the command to asserting the state of the world - // through what is printed/on disk/etc. This is a stop-gap to allow tests - // that are time intensive to convert to continue setting the npm command - // this way. TODO: remove setCmd from all tests and remove the setCmd - // method from `lib/npm.js` - npm.setCmd(command) - } mockCommand.cmd = new Cmd(npm) mockCommand[command] = { usage: Cmd.describeUsage, @@ -308,7 +299,7 @@ const setupMockNpm = async (t, { .join('\n') }, timingFile: async () => { - const data = await fs.readFile(npm.timingFile, 'utf8') + const data = await fs.readFile(npm.logPath + 'timing.json', 'utf8') return JSON.parse(data) }, } diff --git a/deps/npm/test/fixtures/sandbox.js b/deps/npm/test/fixtures/sandbox.js deleted file mode 100644 index 5be02fcf80c1eb..00000000000000 --- a/deps/npm/test/fixtures/sandbox.js +++ /dev/null @@ -1,336 +0,0 @@ -const { createHook, executionAsyncId } = require('async_hooks') -const { EventEmitter } = require('events') -const { homedir, tmpdir } = require('os') -const { dirname, join } = require('path') -const { mkdir, rm } = require('fs/promises') -const mockLogs = require('./mock-logs') -const pkg = require('../../package.json') - -const chain = new Map() -const sandboxes = new Map() - -// keep a reference to the real process -const _process = process - -createHook({ - init: (asyncId, type, triggerAsyncId, resource) => { - // track parentage of asyncIds - chain.set(asyncId, triggerAsyncId) - }, - before: (asyncId) => { - // find the nearest parent id that has a sandbox - let parent = asyncId - while (chain.has(parent) && !sandboxes.has(parent)) { - parent = chain.get(parent) - } - - process = sandboxes.has(parent) - ? sandboxes.get(parent) - : _process - }, -}).enable() - -const _data = Symbol('sandbox.data') -const _dirs = Symbol('sandbox.dirs') -const _test = Symbol('sandbox.test') -const _mocks = Symbol('sandbox.mocks') -const _npm = Symbol('sandbox.npm') -const _parent = Symbol('sandbox.parent') -const _output = Symbol('sandbox.output') -const _proxy = Symbol('sandbox.proxy') -const _get = Symbol('sandbox.proxy.get') -const _set = Symbol('sandbox.proxy.set') -const _logs = Symbol('sandbox.logs') - -// we can't just replace these values everywhere because they're known to be -// very short strings that could be present all over the place, so we only -// replace them if they're located within quotes for now -const vagueRedactedDefaults = [ - 'editor', - 'shell', -] - -const normalize = (str) => str - .replace(/\r\n/g, '\n') // normalize line endings (for ini) - .replace(/[A-z]:\\/g, '\\') // turn windows roots to posix ones - .replace(/\\+/g, '/') // replace \ with / - -class Sandbox extends EventEmitter { - constructor (test, options = {}) { - super() - - this[_test] = test - this[_mocks] = options.mocks || {} - this[_data] = new Map() - this[_output] = [] - const tempDir = `${test.testdirName}-sandbox` - this[_dirs] = { - temp: tempDir, - global: options.global || join(tempDir, 'global'), - home: options.home || join(tempDir, 'home'), - project: options.project || join(tempDir, 'project'), - cache: options.cache || join(tempDir, 'cache'), - } - - this[_proxy] = new Proxy(_process, { - get: this[_get].bind(this), - set: this[_set].bind(this), - }) - this[_proxy].env = { ...options.env } - this[_proxy].argv = [] - - test.cleanSnapshot = this.cleanSnapshot.bind(this) - test.afterEach(() => this.reset()) - test.teardown(() => this.teardown()) - } - - get config () { - return this[_npm] && this[_npm].config - } - - get logs () { - return this[_logs] - } - - get global () { - return this[_dirs].global - } - - get home () { - return this[_dirs].home - } - - get project () { - return this[_dirs].project - } - - get cache () { - return this[_dirs].cache - } - - get process () { - return this[_proxy] - } - - get output () { - return this[_output].map((line) => line.join(' ')).join('\n') - } - - cleanSnapshot (snapshot) { - let clean = normalize(snapshot) - - const viewer = _process.platform === 'win32' - ? /"browser"([^:]+|$)/g - : /"man"([^:]+|$)/g - - // the global prefix is platform dependent - const realGlobalPrefix = _process.platform === 'win32' - ? dirname(_process.execPath) - : dirname(dirname(_process.execPath)) - - const cache = _process.platform === 'win32' - ? /\{HOME\}\/npm-cache(\r?\n|"|\/|$)/g - : /\{HOME\}\/\.npm(\n|"|\/|$)/g - - // and finally replace some paths we know could be present - clean = clean - .replace(viewer, '"{VIEWER}"$1') - .split(normalize(this[_proxy].execPath)).join('{EXECPATH}') - .split(normalize(_process.execPath)).join('{REALEXECPATH}') - .split(normalize(this.global)).join('{GLOBALPREFIX}') - .split(normalize(realGlobalPrefix)).join('{REALGLOBALREFIX}') - .split(normalize(this.project)).join('{LOCALPREFIX}') - .split(normalize(this.home)).join('{HOME}') - .replace(cache, '{CACHE}$1') - .split(normalize(dirname(dirname(__dirname)))).join('{NPMDIR}') - .split(normalize(tmpdir())).join('{TMP}') - .split(normalize(homedir())).join('{REALHOME}') - .split(this[_proxy].platform).join('{PLATFORM}') - .split(this[_proxy].arch).join('{ARCH}') - .replace(new RegExp(process.version, 'g'), '{NODE-VERSION}') - .replace(new RegExp(pkg.version, 'g'), '{NPM-VERSION}') - - // We do the defaults after everything else so that they don't cause the - // other cleaners to miss values we would have clobbered here. For - // instance if execPath is /home/user/.nvm/versions/node/1.0.0/bin/node, - // and we replaced the node version first, the real execPath we're trying - // to replace would no longer be represented, and be missed. - if (this[_npm]) { - // replace vague default config values that are present within quotes - // with placeholders - for (const name of vagueRedactedDefaults) { - const value = this[_npm].config.defaults[name] - clean = clean.split(`"${normalize(value)}"`).join(`"{${name.toUpperCase()}}"`) - } - } - - return clean - } - - // test.afterEach hook - reset () { - this.removeAllListeners() - this[_parent] = undefined - this[_output] = [] - this[_data].clear() - this[_proxy].env = {} - this[_proxy].argv = [] - this[_npm] = undefined - } - - // test.teardown hook - teardown () { - if (this[_parent]) { - const sandboxProcess = sandboxes.get(this[_parent]) - sandboxProcess.removeAllListeners('log') - sandboxes.delete(this[_parent]) - } - if (this[_npm]) { - this[_npm].unload() - } - return rm(this[_dirs].temp, { recursive: true, force: true }).catch(() => null) - } - - // proxy get handler - [_get] (target, prop, receiver) { - if (this[_data].has(prop)) { - return this[_data].get(prop) - } - - if (this[prop] !== undefined) { - return Reflect.get(this, prop, this) - } - - return Reflect.get(target, prop, receiver) - } - - // proxy set handler - [_set] (target, prop, value) { - if (prop === 'env') { - value = { - ...value, - HOME: this.home, - } - } - - if (prop === 'argv') { - value = [ - process.execPath, - join(dirname(process.execPath), 'npm'), - ...value, - ] - } - - return this[_data].set(prop, value) - } - - async run (command, argv = []) { - await Promise.all([ - mkdir(this.project, { recursive: true }), - mkdir(this.home, { recursive: true }), - mkdir(this.global, { recursive: true }), - ]) - - // attach the sandbox process now, doing it after the promise above is - // necessary to make sure that only async calls spawned as part of this - // call to run will receive the sandbox. if we attach it too early, we - // end up interfering with tap - this[_parent] = executionAsyncId() - this[_data].set('_asyncId', this[_parent]) - sandboxes.set(this[_parent], this[_proxy]) - process = this[_proxy] - - this[_proxy].argv = [ - '--prefix', this.project, - '--userconfig', join(this.home, '.npmrc'), - '--globalconfig', join(this.global, 'npmrc'), - '--cache', this.cache, - command, - ...argv, - ] - - const mockedLogs = mockLogs(this[_mocks]) - this[_logs] = mockedLogs.logs - const definitions = this[_test].mock('@npmcli/config/lib/definitions') - const Npm = this[_test].mock('../../lib/npm.js', { - '@npmcli/config/lib/definitions': definitions, - '../../lib/utils/update-notifier.js': async () => {}, - ...this[_mocks], - ...mockedLogs.logMocks, - }) - this.process.on('log', (l, ...args) => { - if (l !== 'pause' && l !== 'resume') { - this[_logs].push([l, ...args]) - } - }) - - this[_npm] = new Npm() - this[_npm].output = (...args) => this[_output].push(args) - await this[_npm].load() - - const cmd = this[_npm].argv.shift() - return this[_npm].exec(cmd, this[_npm].argv) - } - - async complete (command, argv, partial) { - if (!Array.isArray(argv)) { - partial = argv - argv = [] - } - - await Promise.all([ - mkdir(this.project, { recursive: true }), - mkdir(this.home, { recursive: true }), - mkdir(this.global, { recursive: true }), - ]) - - // attach the sandbox process now, doing it after the promise above is - // necessary to make sure that only async calls spawned as part of this - // call to run will receive the sandbox. if we attach it too early, we - // end up interfering with tap - this[_parent] = executionAsyncId() - this[_data].set('_asyncId', this[_parent]) - sandboxes.set(this[_parent], this[_proxy]) - process = this[_proxy] - - this[_proxy].argv = [ - '--prefix', this.project, - '--userconfig', join(this.home, '.npmrc'), - '--globalconfig', join(this.global, 'npmrc'), - '--cache', this.cache, - command, - ...argv, - ] - - const mockedLogs = mockLogs(this[_mocks]) - this[_logs] = mockedLogs.logs - const definitions = this[_test].mock('@npmcli/config/lib/definitions') - const Npm = this[_test].mock('../../lib/npm.js', { - '@npmcli/config/lib/definitions': definitions, - '../../lib/utils/update-notifier.js': async () => {}, - ...this[_mocks], - ...mockedLogs.logMocks, - }) - this.process.on('log', (l, ...args) => { - if (l !== 'pause' && l !== 'resume') { - this[_logs].push([l, ...args]) - } - }) - - this[_npm] = new Npm() - this[_npm].output = (...args) => this[_output].push(args) - await this[_npm].load() - - const Cmd = Npm.cmd(command) - return Cmd.completion({ - partialWord: partial, - conf: { - argv: { - remain: ['npm', command, ...argv], - }, - }, - }) - } -} - -module.exports = Sandbox diff --git a/deps/npm/test/lib/fixtures/sigstore/valid-sigstore-attestations.json b/deps/npm/test/fixtures/sigstore/valid-sigstore-attestations.json similarity index 100% rename from deps/npm/test/lib/fixtures/sigstore/valid-sigstore-attestations.json rename to deps/npm/test/fixtures/sigstore/valid-sigstore-attestations.json diff --git a/deps/npm/test/lib/fixtures/sigstore/valid-tuf-js-attestations.json b/deps/npm/test/fixtures/sigstore/valid-tuf-js-attestations.json similarity index 100% rename from deps/npm/test/lib/fixtures/sigstore/valid-tuf-js-attestations.json rename to deps/npm/test/fixtures/sigstore/valid-tuf-js-attestations.json diff --git a/deps/npm/test/lib/arborist-cmd.js b/deps/npm/test/lib/arborist-cmd.js index 44afe9763f620c..dd90d47b9a0003 100644 --- a/deps/npm/test/lib/arborist-cmd.js +++ b/deps/npm/test/lib/arborist-cmd.js @@ -117,7 +117,8 @@ t.test('arborist-cmd', async t => { chdir: (dirs) => dirs.testdir, }) - npm.localPrefix = prefix + // TODO there has to be a better way to do this + npm.config.localPrefix = prefix await cmd.execWorkspaces([]) t.same(cmd.workspaceNames, ['a', 'c'], 'should set array with single ws name') @@ -127,7 +128,7 @@ t.test('arborist-cmd', async t => { t.test('handle getWorkspaces raising an error', async t => { const { cmd } = await mockArboristCmd(t, null, 'a', { mocks: { - '{LIB}/workspaces/get-workspaces.js': async () => { + '{LIB}/utils/get-workspaces.js': async () => { throw new Error('oopsie') }, }, @@ -212,7 +213,7 @@ t.test('location detection and audit', async (t) => { }) t.equal(npm.config.get('location'), 'user') t.equal(npm.config.get('audit'), true) - t.equal(logs.warn[0][0], 'config') - t.equal(logs.warn[0][1], 'includes both --global and --audit, which is currently unsupported.') + t.equal(logs.warn[0], + 'config includes both --global and --audit, which is currently unsupported.') }) }) diff --git a/deps/npm/test/lib/cli.js b/deps/npm/test/lib/cli.js index a6cb576e886ee9..6c3079b8efe31e 100644 --- a/deps/npm/test/lib/cli.js +++ b/deps/npm/test/lib/cli.js @@ -3,7 +3,7 @@ const tmock = require('../fixtures/tmock') t.test('returns cli-entry function', async t => { const cli = tmock(t, '{LIB}/cli.js', { - '{LIB}/cli-entry.js': () => 'ENTRY', + '{LIB}/cli/entry.js': () => 'ENTRY', }) t.equal(cli(process), 'ENTRY') diff --git a/deps/npm/test/lib/cli-entry.js b/deps/npm/test/lib/cli/entry.js similarity index 52% rename from deps/npm/test/lib/cli-entry.js rename to deps/npm/test/lib/cli/entry.js index 22dca32f1a934e..60a38b70abf895 100644 --- a/deps/npm/test/lib/cli-entry.js +++ b/deps/npm/test/lib/cli/entry.js @@ -1,7 +1,9 @@ const t = require('tap') -const { load: loadMockNpm } = require('../fixtures/mock-npm.js') -const tmock = require('../fixtures/tmock.js') -const validateEngines = require('../../lib/es6/validate-engines.js') +const { readdirSync } = require('fs') +const { dirname } = require('path') +const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') +const tmock = require('../../fixtures/tmock.js') +const validateEngines = require('../../../lib/cli/validate-engines.js') const cliMock = async (t, opts) => { let exitHandlerArgs = null @@ -12,62 +14,56 @@ const cliMock = async (t, opts) => { } exitHandlerMock.setNpm = _npm => npm = _npm - const { Npm, outputs, logMocks, logs } = await loadMockNpm(t, { ...opts, init: false }) - const cli = tmock(t, '{LIB}/cli-entry.js', { + const { Npm, ...mock } = await loadMockNpm(t, { ...opts, init: false }) + const cli = tmock(t, '{LIB}/cli/entry.js', { '{LIB}/npm.js': Npm, - '{LIB}/utils/exit-handler.js': exitHandlerMock, - ...logMocks, + '{LIB}/cli/exit-handler.js': exitHandlerMock, }) return { + ...mock, Npm, cli: (p) => validateEngines(p, () => cli), - outputs, exitHandlerCalled: () => exitHandlerArgs, exitHandlerNpm: () => npm, - logs, - logsBy: (title) => logs.verbose.filter(([p]) => p === title).map(([p, ...rest]) => rest), } } t.test('print the version, and treat npm_g as npm -g', async t => { - const { logsBy, logs, cli, Npm, outputs, exitHandlerCalled } = await cliMock(t, { - globals: { 'process.argv': ['node', 'npm_g', '-v'] }, + const { logs, cli, Npm, outputs, exitHandlerCalled } = await cliMock(t, { + globals: { 'process.argv': ['node', 'npm_g', 'root'] }, }) await cli(process) - t.strictSame(process.argv, ['node', 'npm', '-g', '-v'], 'system process.argv was rewritten') - t.strictSame(logsBy('cli'), [['node npm']]) - t.strictSame(logsBy('title'), [['npm']]) - t.match(logsBy('argv'), [['"--global" "--version"']]) - t.strictSame(logs.info, [ - ['using', 'npm@%s', Npm.version], - ['using', 'node@%s', process.version], - ]) + t.strictSame(process.argv, ['node', 'npm', '-g', 'root'], 'system process.argv was rewritten') + t.strictSame(logs.verbose.byTitle('cli'), ['cli node npm']) + t.strictSame(logs.verbose.byTitle('title'), ['title npm root']) + t.match(logs.verbose.byTitle('argv'), ['argv "--global" "root"']) + t.strictSame(logs.info, [`using npm@${Npm.version}`, `using node@${process.version}`]) t.equal(outputs.length, 1) - t.strictSame(outputs, [[Npm.version]]) + t.match(outputs[0], dirname(process.cwd())) t.strictSame(exitHandlerCalled(), []) }) t.test('calling with --versions calls npm version with no args', async t => { - const { logsBy, cli, outputs, exitHandlerCalled } = await cliMock(t, { + const { logs, cli, outputs, exitHandlerCalled } = await cliMock(t, { globals: { - 'process.argv': ['node', 'npm', 'install', 'or', 'whatever', '--versions'], + 'process.argv': ['node', 'npm', 'install', 'or', 'whatever', '--versions', '--json'], }, }) await cli(process) t.equal(process.title, 'npm install or whatever') - t.strictSame(logsBy('cli'), [['node npm']]) - t.strictSame(logsBy('title'), [['npm install or whatever']]) - t.match(logsBy('argv'), [['"install" "or" "whatever" "--versions"']]) + t.strictSame(logs.verbose.byTitle('cli'), ['cli node npm']) + t.strictSame(logs.verbose.byTitle('title'), ['title npm install or whatever']) + t.match(logs.verbose.byTitle('argv'), ['argv "install" "or" "whatever" "--versions"']) t.equal(outputs.length, 1) - t.match(outputs[0][0], { npm: String, node: String, v8: String }) + t.match(JSON.parse(outputs[0]), { npm: String, node: String, v8: String }) t.strictSame(exitHandlerCalled(), []) }) t.test('logged argv is sanitized', async t => { - const { logsBy, cli } = await cliMock(t, { + const { logs, cli } = await cliMock(t, { globals: { 'process.argv': [ 'node', @@ -81,13 +77,14 @@ t.test('logged argv is sanitized', async t => { await cli(process) t.equal(process.title, 'npm version') - t.strictSame(logsBy('cli'), [['node npm']]) - t.strictSame(logsBy('title'), [['npm version']]) - t.match(logsBy('argv'), [['"version" "--registry" "https://u:***@npmjs.org/password"']]) + t.strictSame(logs.verbose.byTitle('cli'), ['cli node npm']) + t.strictSame(logs.verbose.byTitle('title'), ['title npm version']) + t.match(logs.verbose.byTitle('argv'), + ['argv "version" "--registry" "https://u:***@npmjs.org/password"']) }) t.test('logged argv is sanitized with equals', async t => { - const { logsBy, cli } = await cliMock(t, { + const { logs, cli } = await cliMock(t, { globals: { 'process.argv': [ 'node', @@ -99,7 +96,7 @@ t.test('logged argv is sanitized with equals', async t => { }) await cli(process) - t.match(logsBy('argv'), [['"version" "--registry" "https://u:***@npmjs.org/"']]) + t.match(logs.verbose.byTitle('argv'), ['argv "version" "--registry" "https://u:***@npmjs.org"']) }) t.test('print usage if no params provided', async t => { @@ -110,7 +107,7 @@ t.test('print usage if no params provided', async t => { }) await cli(process) - t.match(outputs[0][0], 'Usage:', 'outputs npm usage') + t.match(outputs[0], 'Usage:', 'outputs npm usage') t.match(exitHandlerCalled(), [], 'should call exitHandler with no args') t.ok(exitHandlerNpm(), 'exitHandler npm is set') t.match(process.exitCode, 1) @@ -124,8 +121,8 @@ t.test('print usage if non-command param provided', async t => { }) await cli(process) - t.match(outputs[0][0], 'Unknown command: "tset"') - t.match(outputs[0][0], 'Did you mean this?') + t.match(outputs[0], 'Unknown command: "tset"') + t.match(outputs[0], 'Did you mean this?') t.match(exitHandlerCalled(), [], 'should call exitHandler with no args') t.ok(exitHandlerNpm(), 'exitHandler npm is set') t.match(process.exitCode, 1) @@ -157,7 +154,31 @@ t.test('unsupported node version', async t => { }) await cli(process) t.match( - logs.warn[0][1], + logs.warn[0], /npm v.* does not support Node\.js 12\.6\.0\./ ) }) + +t.test('non-ascii dash', async t => { + const { cli, logs } = await cliMock(t, { + globals: { + 'process.argv': ['node', 'npm', 'scope', '\u2010not-a-dash'], + }, + }) + await cli(process) + t.equal( + logs.error[0], + 'arg Argument starts with non-ascii dash, this is probably invalid: \u2010not-a-dash' + ) +}) + +t.test('exit early for --version', async t => { + const { cli, outputs, Npm, cache } = await cliMock(t, { + globals: { + 'process.argv': ['node', 'npm', '-v'], + }, + }) + await cli(process) + t.strictSame(readdirSync(cache), [], 'nothing created in cache') + t.equal(outputs[0], Npm.version) +}) diff --git a/deps/npm/test/lib/utils/exit-handler.js b/deps/npm/test/lib/cli/exit-handler.js similarity index 69% rename from deps/npm/test/lib/utils/exit-handler.js rename to deps/npm/test/lib/cli/exit-handler.js index b48f96d581775a..7b465643504c76 100644 --- a/deps/npm/test/lib/utils/exit-handler.js +++ b/deps/npm/test/lib/cli/exit-handler.js @@ -1,14 +1,15 @@ +const fs = require('node:fs') +const { join, resolve } = require('node:path') +const EventEmitter = require('node:events') +const os = require('node:os') const t = require('tap') -const os = require('os') -const fs = require('fs') const fsMiniPass = require('fs-minipass') -const { join, resolve } = require('path') -const EventEmitter = require('events') -const { format } = require('../../../lib/utils/log-file') +const { output, time } = require('proc-log') const { load: loadMockNpm } = require('../../fixtures/mock-npm') const mockGlobals = require('@npmcli/mock-globals') const { cleanCwd, cleanDate } = require('../../fixtures/clean-snapshot') const tmock = require('../../fixtures/tmock') +const { version: NPM_VERSION } = require('../../../package.json') const pick = (obj, ...keys) => keys.reduce((acc, key) => { acc[key] = obj[key] @@ -32,6 +33,9 @@ t.cleanSnapshot = (path) => cleanDate(cleanCwd(path)) .replace(/.*silly logfile.*cleaning.*\n/gm, '') .replace(/(Completed in )\d+(ms)/g, '$1{TIME}$2') .replace(/(removing )\d+( files)/g, '$1${NUM}2') + .replaceAll(`node ${process.version}`, '{NODE-VERSION}') + .replaceAll(`${os.type()} ${os.release()}`, '{OS}') + .replaceAll(`v${NPM_VERSION}`, '{NPM-VERSION}') // cut off process from script so that it won't quit the test runner // while trying to run through the myriad of cases. need to make it @@ -40,9 +44,9 @@ t.cleanSnapshot = (path) => cleanDate(cleanCwd(path)) mockGlobals(t, { process: Object.assign(new EventEmitter(), { // these are process properties that are needed in the running code and tests - ...pick(process, 'execPath', 'stdout', 'stderr', 'stdin', 'cwd', 'chdir', 'env', 'umask'), + // eslint-disable-next-line max-len + ...pick(process, 'version', 'execPath', 'stdout', 'stderr', 'stdin', 'cwd', 'chdir', 'env', 'umask'), argv: ['/node', ...process.argv.slice(1)], - version: 'v1.0.0', kill: () => {}, reallyExit: (code) => process.exit(code), pid: 123456, @@ -56,14 +60,9 @@ mockGlobals(t, { const mockExitHandler = async (t, { config, mocks, files, ...opts } = {}) => { const errors = [] - const { npm, logMocks, ...rest } = await loadMockNpm(t, { + const { npm, ...rest } = await loadMockNpm(t, { ...opts, - mocks: { - '{ROOT}/package.json': { - version: '1.0.0', - }, - ...mocks, - }, + mocks, config: (dirs) => ({ loglevel: 'notice', ...(typeof config === 'function' ? config(dirs) : config), @@ -73,24 +72,17 @@ const mockExitHandler = async (t, { config, mocks, files, ...opts } = {}) => { }, }) - const exitHandler = tmock(t, '{LIB}/utils/exit-handler.js', { + const exitHandler = tmock(t, '{LIB}/cli/exit-handler.js', { '{LIB}/utils/error-message.js': (err) => ({ summary: [['ERR SUMMARY', err.message]], detail: [['ERR DETAIL', err.message]], ...(files ? { files } : {}), json: { - error: { - code: err.code, - summary: err.message, - detail: err.message, - }, + code: err.code, + summary: err.message, + detail: err.message, }, }), - os: { - type: () => 'Foo', - release: () => '1.0.0', - }, - ...logMocks, ...mocks, }) @@ -104,7 +96,10 @@ const mockExitHandler = async (t, { config, mocks, files, ...opts } = {}) => { return { ...rest, - errors, + errors: () => [ + ...rest.outputErrors, + ...errors, + ], npm, // Make it async to make testing ergonomics a little easier so we dont need // to t.plan() every test to make sure we get process.exit called. @@ -129,11 +124,11 @@ const err = (message = '', options = {}, noStack = false) => { } t.test('handles unknown error with logs and debug file', async (t) => { - const { exitHandler, debugFile, logs } = await mockExitHandler(t) + const { exitHandler, debugFile, logs } = await mockExitHandler(t, { + config: { loglevel: 'silly', timing: true }, + }) await exitHandler(err('Unknown error', 'ECODE')) - // force logfile cleaning logs to happen since those are purposefully not awaited - await require('timers/promises').setTimeout(200) const fileLogs = await debugFile() const fileLines = fileLogs.split('\n') @@ -143,23 +138,18 @@ t.test('handles unknown error with logs and debug file', async (t) => { t.equal(process.exitCode, 1) - let skippedLogs = 0 logs.forEach((logItem, i) => { - const logLines = format(i, ...logItem).trim().split(os.EOL) + const logLines = logItem.split('\n').map(l => `${i} ${l}`) for (const line of logLines) { - if (line.includes('logfile') && line.includes('cleaning')) { - skippedLogs++ - continue - } t.match(fileLogs.trim(), line, 'log appears in debug file') } }) - t.equal(logs.length - skippedLogs, parseInt(lastLog) + 1) + t.equal(logs.length, parseInt(lastLog) + 1) t.match(logs.error, [ - ['code', 'ECODE'], - ['ERR SUMMARY', 'Unknown error'], - ['ERR DETAIL', 'Unknown error'], + 'code ECODE', + 'ERR SUMMARY Unknown error', + 'ERR DETAIL Unknown error', ]) t.match(fileLogs, /\d+ error code ECODE/) t.match(fileLogs, /\d+ error ERR SUMMARY Unknown error/) @@ -173,11 +163,8 @@ t.test('exit handler never called - loglevel silent', async (t) => { config: { loglevel: 'silent' }, }) process.emit('exit', 1) - t.match(logs.error, [ - ['', /Exit handler never called/], - ['', /error with npm itself/], - ]) - t.strictSame(errors, [''], 'logs one empty string to console.error') + t.strictSame(logs.error, []) + t.strictSame(errors(), [''], 'one empty string') }) t.test('exit handler never called - loglevel notice', async (t) => { @@ -185,45 +172,45 @@ t.test('exit handler never called - loglevel notice', async (t) => { process.emit('exit', 1) t.equal(process.exitCode, 1) t.match(logs.error, [ - ['', /Exit handler never called/], - ['', /error with npm itself/], + 'Exit handler never called!', + /error with npm itself/, ]) - t.strictSame(errors, ['', ''], 'logs two empty strings to console.error') + t.strictSame(errors(), ['', ''], 'two empty string on output') }) t.test('exit handler never called - no npm', async (t) => { const { logs, errors } = await mockExitHandler(t, { init: false }) process.emit('exit', 1) t.equal(process.exitCode, 1) - t.match(logs.error, [ - ['', /Exit handler never called/], - ['', /error with npm itself/], - ]) - t.strictSame(errors, [''], 'logs one empty string to console.error') + t.strictSame(logs.error, []) + t.strictSame(errors(), [''], 'one empty string') }) t.test('exit handler called - no npm', async (t) => { const { exitHandler, errors } = await mockExitHandler(t, { init: false }) await exitHandler() t.equal(process.exitCode, 1) - t.match(errors, [/Error: Exit prior to setting npm in exit handler/]) + t.equal(errors().length, 1) + t.match(errors(), [/Error: Exit prior to setting npm in exit handler/]) }) t.test('exit handler called - no npm with error', async (t) => { const { exitHandler, errors } = await mockExitHandler(t, { init: false }) await exitHandler(err('something happened')) t.equal(process.exitCode, 1) - t.match(errors, [/Error: something happened/]) + t.equal(errors().length, 1) + t.match(errors(), [/Error: something happened/]) }) t.test('exit handler called - no npm with error without stack', async (t) => { const { exitHandler, errors } = await mockExitHandler(t, { init: false }) await exitHandler(err('something happened', {}, true)) t.equal(process.exitCode, 1) - t.match(errors, [/something happened/]) + t.equal(errors().length, 1) + t.match(errors(), [/something happened/]) }) -t.test('console.log output using --json', async (t) => { +t.test('standard output using --json', async (t) => { const { exitHandler, outputs } = await mockExitHandler(t, { config: { json: true }, }) @@ -245,13 +232,13 @@ t.test('console.log output using --json', async (t) => { }) t.test('merges output buffers errors with --json', async (t) => { - const { exitHandler, outputs, npm } = await mockExitHandler(t, { + const { exitHandler, outputs } = await mockExitHandler(t, { config: { json: true }, }) - npm.outputBuffer({ output_data: 1 }) - npm.outputBuffer(JSON.stringify({ more_data: 2 })) - npm.outputBuffer('not json, will be ignored') + output.buffer({ output_data: 1 }) + output.buffer(JSON.stringify({ more_data: 2 })) + output.buffer('not json, will be ignored') await exitHandler(err('Error: EBADTHING Something happened')) @@ -272,20 +259,20 @@ t.test('merges output buffers errors with --json', async (t) => { }) t.test('output buffer without json', async (t) => { - const { exitHandler, outputs, npm, logs } = await mockExitHandler(t) + const { exitHandler, outputs, logs } = await mockExitHandler(t) - npm.outputBuffer('output_data') - npm.outputBuffer('more_data') + output.buffer('output_data') + output.buffer('more_data') await exitHandler(err('Error: EBADTHING Something happened')) t.equal(process.exitCode, 1) t.same( outputs, - [['output_data'], ['more_data']], + ['output_data', 'more_data'], 'should output expected output' ) - t.match(logs.error, [['code', 'EBADTHING']]) + t.match(logs.error, ['code EBADTHING']) }) t.test('throw a non-error obj', async (t) => { @@ -298,7 +285,7 @@ t.test('throw a non-error obj', async (t) => { t.equal(process.exitCode, 1) t.match(logs.error, [ - ['weird error', { code: 'ESOMETHING', message: 'foo bar' }], + "weird error { code: 'ESOMETHING', message: 'foo bar' }", ]) }) @@ -309,21 +296,34 @@ t.test('throw a string error', async (t) => { t.equal(process.exitCode, 1) t.match(logs.error, [ - ['', 'foo bar'], + 'foo bar', ]) }) -t.test('update notification', async (t) => { - const { exitHandler, logs, npm } = await mockExitHandler(t) +t.test('update notification - shows even with loglevel error', async (t) => { + const { exitHandler, logs, npm } = await mockExitHandler(t, { + config: { loglevel: 'error' }, + }) npm.updateNotification = 'you should update npm!' await exitHandler() t.match(logs.notice, [ - ['', 'you should update npm!'], + 'you should update npm!', ]) }) +t.test('update notification - hidden with silent', async (t) => { + const { exitHandler, logs, npm } = await mockExitHandler(t, { + config: { loglevel: 'silent' }, + }) + npm.updateNotification = 'you should update npm!' + + await exitHandler() + + t.strictSame(logs.notice, []) +}) + t.test('npm.config not ready', async (t) => { const { exitHandler, logs, errors } = await mockExitHandler(t, { load: false, @@ -332,12 +332,11 @@ t.test('npm.config not ready', async (t) => { await exitHandler() t.equal(process.exitCode, 1) - t.match(errors, [ + t.equal(errors().length, 1) + t.match(errors(), [ /Error: Exit prior to config file resolving./, ], 'should exit with config error msg') - t.match(logs.verbose, [ - ['stack', /Error: Exit prior to config file resolving./], - ], 'should exit with config error msg') + t.strictSame(logs, [], 'no logs if it doesnt load') }) t.test('no logs dir', async (t) => { @@ -346,69 +345,62 @@ t.test('no logs dir', async (t) => { }) await exitHandler(new Error()) - t.match(logs.error.filter(([t]) => t === ''), [ - ['', 'Log files were not written due to the config logs-max=0'], - ]) - t.match(logs.filter(([_, task]) => task === 'npm.load.mkdirplogs'), []) + t.match(logs.error[2], + 'Log files were not written due to the config logs-max=0') + t.match(logs.filter((l) => l.includes('npm.load.mkdirplogs')), []) }) t.test('timers fail to write', async (t) => { - // we want the fs.writeFileSync in the Timers class to fail - const mockTimers = tmock(t, '{LIB}/utils/timers.js', { - fs: { - ...fs, - writeFileSync: (file, ...rest) => { - if (file.includes('LOGS_DIR')) { - throw new Error('err') - } - - return fs.writeFileSync(file, ...rest) - }, - }, - }) - const { exitHandler, logs } = await mockExitHandler(t, { config: (dirs) => ({ 'logs-dir': resolve(dirs.prefix, 'LOGS_DIR'), timing: true, }), mocks: { - // note, this is relative to test/fixtures/mock-npm.js not this file - '{LIB}/utils/timers.js': mockTimers, + // we want the fs.writeFileSync in the Timers class to fail + '{LIB}/utils/timers.js': tmock(t, '{LIB}/utils/timers.js', { + 'node:fs': { + ...fs, + writeFileSync: (file, ...rest) => { + if (file.includes('LOGS_DIR')) { + throw new Error('err') + } + + return fs.writeFileSync(file, ...rest) + }, + }, + }), }, }) await exitHandler(new Error()) - t.match(logs.error.filter(([t]) => t === ''), [['', `error writing to the directory`]]) + t.match(logs.warn[0], `timing could not write timing file: Error: err`) }) t.test('log files fail to write', async (t) => { - // we want the fsMiniPass.WriteStreamSync in the LogFile class to fail - const mockLogFile = tmock(t, '{LIB}/utils/log-file.js', { - 'fs-minipass': { - ...fsMiniPass, - WriteStreamSync: (file, ...rest) => { - if (file.includes('LOGS_DIR')) { - throw new Error('err') - } - }, - }, - }) - const { exitHandler, logs } = await mockExitHandler(t, { config: (dirs) => ({ 'logs-dir': resolve(dirs.prefix, 'LOGS_DIR'), }), mocks: { - // note, this is relative to test/fixtures/mock-npm.js not this file - '{LIB}/utils/log-file.js': mockLogFile, + // we want the fsMiniPass.WriteStreamSync in the LogFile class to fail + '{LIB}/utils/log-file.js': tmock(t, '{LIB}/utils/log-file.js', { + 'fs-minipass': { + ...fsMiniPass, + WriteStreamSync: (file) => { + if (file.includes('LOGS_DIR')) { + throw new Error('err') + } + }, + }, + }), }, }) await exitHandler(new Error()) - t.match(logs.error.filter(([t]) => t === ''), [['', `error writing to the directory`]]) + t.match(logs.error[2], `error writing to the directory`) }) t.test('files from error message', async (t) => { @@ -424,9 +416,7 @@ t.test('files from error message', async (t) => { const errorFileName = logFiles.find(f => f.endsWith('error-file.txt')) const errorFile = fs.readFileSync(join(cache, '_logs', errorFileName)).toString() - const [log] = logs.error.filter(([t]) => t === '') - - t.match(log[1], /For a full report see:\n.*-error-file\.txt/) + t.match(logs[2], /For a full report see:\n.*-error-file\.txt/) t.match(errorFile, '# error file content') t.match(errorFile, 'Log files:') }) @@ -440,7 +430,7 @@ t.test('files from error message with error', async (t) => { ['error-file.txt', '# error file content'], ], mocks: { - fs: { + 'node:fs': { ...fs, writeFileSync: (dir) => { if (dir.includes('LOGS_DIR') && dir.endsWith('error-file.txt')) { @@ -453,14 +443,12 @@ t.test('files from error message with error', async (t) => { await exitHandler(err('Error message')) - const [log] = logs.warn.filter(([t]) => t === '') - - t.match(log[1], /Could not write error message to.*error-file\.txt.*err/) + t.match(logs.warn[0], /Could not write error message to.*error-file\.txt.*err/) }) t.test('timing with no error', async (t) => { const { exitHandler, timingFile, npm, logs } = await mockExitHandler(t, { - config: { timing: true }, + config: { timing: true, loglevel: 'silly' }, }) await exitHandler() @@ -468,47 +456,50 @@ t.test('timing with no error', async (t) => { t.equal(process.exitCode, 0) - const msg = logs.info.filter(([t]) => t === '')[0][1] - t.match(msg, /A complete log of this run can be found in:/) + const msg = logs.info.byTitle('timing')[0] t.match(msg, /Timing info written to:/) - t.match( - timingFileData.timers, - Object.keys(npm.finishedTimers).reduce((acc, k) => { - acc[k] = Number - return acc - }, {}) - ) - t.strictSame(npm.unfinishedTimers, new Map()) t.match(timingFileData, { metadata: { command: [], - version: '1.0.0', + version: npm.version, logfiles: [String], }, timers: { + 'npm:load': Number, npm: Number, }, }) }) +t.test('timing message hidden by loglevel', async (t) => { + const { exitHandler, logs } = await mockExitHandler(t, { + config: { timing: true, loglevel: 'notice' }, + }) + + await exitHandler() + + t.equal(process.exitCode, 0) + + t.strictSame(logs.info, [], 'no log message') +}) + t.test('unfinished timers', async (t) => { const { exitHandler, timingFile, npm } = await mockExitHandler(t, { config: { timing: true }, }) - process.emit('time', 'foo') - process.emit('time', 'bar') + time.start('foo') + time.start('bar') await exitHandler() const timingFileData = await timingFile() t.equal(process.exitCode, 0) - t.match(npm.unfinishedTimers, new Map([['foo', Number], ['bar', Number]])) t.match(timingFileData, { metadata: { command: [], - version: '1.0.0', + version: npm.version, logfiles: [String], }, timers: { @@ -526,7 +517,7 @@ t.test('uses code from errno', async (t) => { await exitHandler(err('Error with errno', { errno: 127 })) t.equal(process.exitCode, 127) - t.match(logs.error, [['errno', 127]]) + t.match(logs.error, ['errno 127']) }) t.test('uses code from number', async (t) => { @@ -534,7 +525,7 @@ t.test('uses code from number', async (t) => { await exitHandler(err('Error with code type number', 404)) t.equal(process.exitCode, 404) - t.match(logs.error, [['code', 404]]) + t.match(logs.error, ['code 404']) }) t.test('uses all err special properties', async t => { @@ -548,11 +539,13 @@ t.test('uses all err special properties', async t => { await exitHandler(err('Error with code type number', properties)) t.equal(process.exitCode, 1) - t.match(logs.error, keys.map((k) => [k, `${k}-hey`]), 'all special keys get logged') + t.match(logs.error, keys.map((k) => `${k} ${k}-hey`), 'all special keys get logged') }) t.test('verbose logs replace info on err props', async t => { - const { exitHandler, logs } = await mockExitHandler(t) + const { exitHandler, logs } = await mockExitHandler(t, { + config: { loglevel: 'verbose' }, + }) const keys = ['type', 'stack', 'pkgid'] const properties = keys.reduce((acc, k) => { @@ -563,8 +556,8 @@ t.test('verbose logs replace info on err props', async t => { await exitHandler(err('Error with code type number', properties)) t.equal(process.exitCode, 1) t.match( - logs.verbose.filter(([p]) => !['logfile', 'title', 'argv'].includes(p)), - keys.map((k) => [k, `${k}-https://user:***@registry.npmjs.org/`]), + logs.verbose.filter(l => !/^(logfile|title|argv)/.test(l)), + keys.map((k) => `${k} ${k}-https://user:***@registry.npmjs.org/`), 'all special keys get replaced' ) }) @@ -583,11 +576,8 @@ t.test('defaults to log error msg if stack is missing when unloaded', async (t) await exitHandler(err('Error with no stack', { code: 'ENOSTACK', errno: 127 }, true)) t.equal(process.exitCode, 127) - t.same(errors, ['Error with no stack'], 'should use error msg') - t.match(logs.error, [ - ['code', 'ENOSTACK'], - ['errno', 127], - ]) + t.strictSame(errors(), ['Error with no stack'], 'should use error msg') + t.strictSame(logs.error, []) }) t.test('exits uncleanly when only emitting exit event', async (t) => { @@ -595,36 +585,43 @@ t.test('exits uncleanly when only emitting exit event', async (t) => { process.emit('exit') - t.match(logs.error, [['', 'Exit handler never called!']]) + t.match(logs.error, ['Exit handler never called!']) t.equal(process.exitCode, 1, 'exitCode coerced to 1') }) t.test('do no fancy handling for shellouts', async t => { - const { exitHandler, logs } = await mockExitHandler(t, { + const mockShelloutExit = (t) => mockExitHandler(t, { command: 'exec', exec: true, argv: ['-c', 'exit'], + config: { + timing: false, + }, }) - const loudNoises = () => - logs.filter(([level]) => ['warn', 'error'].includes(level)) - t.test('shellout with a numeric error code', async t => { + const { exitHandler, logs, errors } = await mockShelloutExit(t) await exitHandler(err('', 5)) t.equal(process.exitCode, 5, 'got expected exit code') - t.strictSame(loudNoises(), [], 'no noisy warnings') + t.strictSame(logs.error, [], 'no noisy warnings') + t.strictSame(logs.warn, [], 'no noisy warnings') + t.strictSame(errors(), []) }) t.test('shellout without a numeric error code (something in npm)', async t => { + const { exitHandler, logs, errors } = await mockShelloutExit(t) await exitHandler(err('', 'banana stand')) t.equal(process.exitCode, 1, 'got expected exit code') // should log some warnings and errors, because something weird happened - t.strictNotSame(loudNoises(), [], 'bring the noise') + t.strictNotSame(logs.error, [], 'bring the noise') + t.strictSame(errors(), ['']) }) t.test('shellout with code=0 (extra weird?)', async t => { + const { exitHandler, logs, errors } = await mockShelloutExit(t) await exitHandler(Object.assign(new Error(), { code: 0 })) t.equal(process.exitCode, 1, 'got expected exit code') - t.strictNotSame(loudNoises(), [], 'bring the noise') + t.strictNotSame(logs.error, [], 'bring the noise') + t.strictSame(errors(), ['']) }) }) diff --git a/deps/npm/test/lib/utils/update-notifier.js b/deps/npm/test/lib/cli/update-notifier.js similarity index 99% rename from deps/npm/test/lib/utils/update-notifier.js rename to deps/npm/test/lib/cli/update-notifier.js index 052367c60dadb1..2d29868b792a17 100644 --- a/deps/npm/test/lib/utils/update-notifier.js +++ b/deps/npm/test/lib/cli/update-notifier.js @@ -83,7 +83,7 @@ const runUpdateNotifier = async (t, { prefixDir, argv, }) - const updateNotifier = tmock(t, '{LIB}/utils/update-notifier.js', mocks) + const updateNotifier = tmock(t, '{LIB}/cli/update-notifier.js', mocks) const result = await updateNotifier(mock.npm) diff --git a/deps/npm/test/lib/es6/validate-engines.js b/deps/npm/test/lib/cli/validate-engines.js similarity index 94% rename from deps/npm/test/lib/es6/validate-engines.js rename to deps/npm/test/lib/cli/validate-engines.js index 0e6bce726af966..1c0b59700a7738 100644 --- a/deps/npm/test/lib/es6/validate-engines.js +++ b/deps/npm/test/lib/cli/validate-engines.js @@ -3,7 +3,7 @@ const mockGlobals = require('@npmcli/mock-globals') const tmock = require('../../fixtures/tmock') const mockValidateEngines = (t) => { - const validateEngines = tmock(t, '{LIB}/es6/validate-engines.js', { + const validateEngines = tmock(t, '{LIB}/cli/validate-engines.js', { '{ROOT}/package.json': { version: '1.2.3', engines: { node: '>=0' } }, }) mockGlobals(t, { 'process.version': 'v4.5.6' }) diff --git a/deps/npm/test/lib/commands/access.js b/deps/npm/test/lib/commands/access.js index 7aec33701297ca..96f1bcd074282e 100644 --- a/deps/npm/test/lib/commands/access.js +++ b/deps/npm/test/lib/commands/access.js @@ -130,8 +130,8 @@ t.test('list', t => { registry.getPackages({ team: '@npm:test-team', packages }) await npm.exec('access', ['list', 'packages', '@npm:test-team']) t.same(outputs, [ - ['@npmcli/other-package: read-write'], - ['@npmcli/test-package: read-only'], + '@npmcli/other-package: read-write', + '@npmcli/test-package: read-only', ]) }) @@ -146,8 +146,8 @@ t.test('list', t => { registry.getPackages({ team: 'npm', packages }) await npm.exec('access', ['list', 'packages']) t.same(outputs, [ - ['@npmcli/other-package: read-write'], - ['@npmcli/test-package: read-only'], + '@npmcli/other-package: read-write', + '@npmcli/test-package: read-only', ]) }) @@ -174,8 +174,8 @@ t.test('list', t => { registry.getCollaborators({ spec: '@npmcli/test-package', collaborators }) await npm.exec('access', ['list', 'collaborators', '@npmcli/test-package']) t.same(outputs, [ - ['github: read-only'], - ['npm: read-write'], + 'github: read-only', + 'npm: read-write', ]) }) @@ -188,7 +188,7 @@ t.test('list', t => { registry.getCollaborators({ spec: '@npmcli/test-package', collaborators }) await npm.exec('access', ['list', 'collaborators', '@npmcli/test-package', 'npm']) t.same(outputs, [ - ['npm: read-write'], + 'npm: read-write', ]) }) t.end() @@ -208,7 +208,7 @@ t.test('get', t => { }) registry.getVisibility({ spec: '@npmcli/test-package', visibility: { public: true } }) await npm.exec('access', ['get', 'status', '@npmcli/test-package']) - t.same(outputs, [['@npmcli/test-package: public']]) + t.same(outputs, ['@npmcli/test-package: public']) }) t.test('status implicit package', async t => { const { npm, outputs } = await loadMockNpm(t, { @@ -222,7 +222,7 @@ t.test('get', t => { }) registry.getVisibility({ spec: '@npmcli/test-package', visibility: { public: true } }) await npm.exec('access', ['get', 'status']) - t.same(outputs, [['@npmcli/test-package: public']]) + t.same(outputs, ['@npmcli/test-package: public']) }) t.test('status no package', async t => { const { npm } = await loadMockNpm(t) @@ -263,7 +263,7 @@ t.test('set', t => { registry.setAccess({ spec: '@npmcli/test-package', body: { access: 'public' } }) registry.getVisibility({ spec: '@npmcli/test-package', visibility: { public: true } }) await npm.exec('access', ['set', 'status=public', '@npmcli/test-package']) - t.same(outputs, [['@npmcli/test-package: public']]) + t.same(outputs, ['@npmcli/test-package: public']) }) t.test('status=private', async t => { const { npm, outputs } = await loadMockNpm(t) @@ -274,7 +274,7 @@ t.test('set', t => { registry.setAccess({ spec: '@npmcli/test-package', body: { access: 'restricted' } }) registry.getVisibility({ spec: '@npmcli/test-package', visibility: { public: false } }) await npm.exec('access', ['set', 'status=private', '@npmcli/test-package']) - t.same(outputs, [['@npmcli/test-package: private']]) + t.same(outputs, ['@npmcli/test-package: private']) }) t.test('status=invalid', async t => { const { npm } = await loadMockNpm(t) diff --git a/deps/npm/test/lib/commands/audit.js b/deps/npm/test/lib/commands/audit.js index 9a57a02184ea18..701d374ade9850 100644 --- a/deps/npm/test/lib/commands/audit.js +++ b/deps/npm/test/lib/commands/audit.js @@ -1860,7 +1860,7 @@ t.test('audit signatures', async t => { ) }) - t.test('with invalid signtaures and color output enabled', async t => { + t.test('with invalid signatures and color output enabled', async t => { const { npm, joinedOutput } = await loadMockNpm(t, { prefixDir: installWithValidSigs, config: { color: 'always' }, @@ -1875,7 +1875,7 @@ t.test('audit signatures', async t => { t.match( joinedOutput(), // eslint-disable-next-line no-control-regex - /\u001b\[1m\u001b\[31minvalid\u001b\[39m\u001b\[22m registry signature/ + /\u001b\[91minvalid\u001b\[39m registry signature/ ) t.matchSnapshot(joinedOutput()) }) @@ -1892,7 +1892,7 @@ t.test('audit signatures', async t => { const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithValidAttestations({ registry }) const fixture = fs.readFileSync( - path.join(__dirname, '..', 'fixtures', 'sigstore/valid-sigstore-attestations.json'), + path.resolve(__dirname, '../../fixtures/sigstore/valid-sigstore-attestations.json'), 'utf8' ) registry.nock.get('/-/npm/v1/attestations/sigstore@1.0.0').reply(200, fixture) @@ -1918,11 +1918,11 @@ t.test('audit signatures', async t => { await manifestWithValidAttestations({ registry }) await manifestWithMultipleValidAttestations({ registry }) const fixture1 = fs.readFileSync( - path.join(__dirname, '..', 'fixtures', 'sigstore/valid-sigstore-attestations.json'), + path.join(__dirname, '../../fixtures/sigstore/valid-sigstore-attestations.json'), 'utf8' ) const fixture2 = fs.readFileSync( - path.join(__dirname, '..', 'fixtures', 'sigstore/valid-tuf-js-attestations.json'), + path.join(__dirname, '../../fixtures/sigstore/valid-tuf-js-attestations.json'), 'utf8' ) registry.nock.get('/-/npm/v1/attestations/sigstore@1.0.0').reply(200, fixture1) @@ -1951,7 +1951,7 @@ t.test('audit signatures', async t => { const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithValidAttestations({ registry }) const fixture = fs.readFileSync( - path.join(__dirname, '..', 'fixtures', 'sigstore/valid-sigstore-attestations.json'), + path.join(__dirname, '../../fixtures/sigstore/valid-sigstore-attestations.json'), 'utf8' ) registry.nock.get('/-/npm/v1/attestations/sigstore@1.0.0').reply(200, fixture) @@ -1986,7 +1986,7 @@ t.test('audit signatures', async t => { const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') }) await manifestWithValidAttestations({ registry }) const fixture = fs.readFileSync( - path.join(__dirname, '..', 'fixtures', 'sigstore/valid-sigstore-attestations.json'), + path.join(__dirname, '../../fixtures/sigstore/valid-sigstore-attestations.json'), 'utf8' ) registry.nock.get('/-/npm/v1/attestations/sigstore@1.0.0').reply(200, fixture) @@ -2016,11 +2016,11 @@ t.test('audit signatures', async t => { await manifestWithValidAttestations({ registry }) await manifestWithMultipleValidAttestations({ registry }) const fixture1 = fs.readFileSync( - path.join(__dirname, '..', 'fixtures', 'sigstore/valid-sigstore-attestations.json'), + path.join(__dirname, '../../fixtures/sigstore/valid-sigstore-attestations.json'), 'utf8' ) const fixture2 = fs.readFileSync( - path.join(__dirname, '..', 'fixtures', 'sigstore/valid-tuf-js-attestations.json'), + path.join(__dirname, '../../fixtures/sigstore/valid-tuf-js-attestations.json'), 'utf8' ) registry.nock.get('/-/npm/v1/attestations/sigstore@1.0.0').reply(200, fixture1) diff --git a/deps/npm/test/lib/commands/ci.js b/deps/npm/test/lib/commands/ci.js index 681ccad7d87a75..c4b855932a9ed5 100644 --- a/deps/npm/test/lib/commands/ci.js +++ b/deps/npm/test/lib/commands/ci.js @@ -142,7 +142,7 @@ t.test('--no-audit and --ignore-scripts', async t => { 'package-lock.json': JSON.stringify(packageLock), }, }) - require('nock').emitter.on('no match', req => { + require('nock').emitter.on('no match', () => { t.fail('Should not audit') }) const manifest = registry.manifest({ name: 'abbrev' }) @@ -164,7 +164,6 @@ t.test('lifecycle scripts', async t => { }, mocks: { '@npmcli/run-script': (opts) => { - t.ok(opts.banner) scripts.push(opts.event) }, }, diff --git a/deps/npm/test/lib/commands/config.js b/deps/npm/test/lib/commands/config.js index b54096fd216f27..0806326e2e8e42 100644 --- a/deps/npm/test/lib/commands/config.js +++ b/deps/npm/test/lib/commands/config.js @@ -3,16 +3,49 @@ const fs = require('fs/promises') const ini = require('ini') const tspawk = require('../../fixtures/tspawk') const t = require('tap') +const { load: _loadMockNpm } = require('../../fixtures/mock-npm') +const { cleanCwd } = require('../../fixtures/clean-snapshot.js') const spawk = tspawk(t) -const Sandbox = require('../../fixtures/sandbox.js') +const replaceJsonOrIni = (key) => [ + new RegExp(`(\\s(?:${key} = |"${key}": )"?)[^"\\n,]+`, 'g'), + `$1{${key.toUpperCase()}}`, +] + +const replaceIniComment = (key) => [ + new RegExp(`(; ${key} = ).*`, 'g'), + `$1{${key.replaceAll(' ', '-').toUpperCase()}}`, +] + +t.cleanSnapshot = (s) => cleanCwd(s) + .replaceAll(...replaceIniComment('node version')) + .replaceAll(...replaceIniComment('npm version')) + .replaceAll(...replaceIniComment('node bin location')) + .replaceAll(...replaceJsonOrIni('npm-version')) + .replaceAll(...replaceJsonOrIni('viewer')) + .replaceAll(...replaceJsonOrIni('shell')) + .replaceAll(...replaceJsonOrIni('editor')) + .replaceAll(...replaceJsonOrIni('progress')) + .replaceAll(...replaceJsonOrIni('color')) + .replaceAll(...replaceJsonOrIni('cache')) + +const loadMockNpm = (t, opts = {}) => _loadMockNpm(t, { + ...opts, + config: { + ...opts.config, + // Reset configs that mock npm sets by default + 'fetch-retries': undefined, + loglevel: undefined, + color: undefined, + }, +}) t.test('config no args', async t => { - const sandbox = new Sandbox(t) + const { npm } = await loadMockNpm(t) await t.rejects( - sandbox.run('config', []), + npm.exec('config', []), { code: 'EUSAGE', }, @@ -21,10 +54,14 @@ t.test('config no args', async t => { }) t.test('config ignores workspaces', async t => { - const sandbox = new Sandbox(t) + const { npm } = await loadMockNpm(t, { + config: { + workspaces: true, + }, + }) await t.rejects( - sandbox.run('config', ['--workspaces']), + npm.exec('config'), { code: 'ENOWORKSPACES', }, @@ -33,74 +70,92 @@ t.test('config ignores workspaces', async t => { }) t.test('config list', async t => { - const temp = t.testdir({ - global: { - npmrc: 'globalloaded=yes', - }, - project: { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: { '.npmrc': 'projectloaded=yes', }, - home: { + globalPrefixDir: { + etc: { + npmrc: 'globalloaded=yes', + }, + }, + homeDir: { '.npmrc': 'userloaded=yes', }, }) - const global = join(temp, 'global') - const project = join(temp, 'project') - const home = join(temp, 'home') - const sandbox = new Sandbox(t, { global, project, home }) - await sandbox.run('config', ['list']) + await npm.exec('config', ['list']) + + const output = joinedOutput() + + t.match(output, 'projectloaded = "yes"') + t.match(output, 'globalloaded = "yes"') + t.match(output, 'userloaded = "yes"') - t.matchSnapshot(sandbox.output, 'output matches snapshot') + t.matchSnapshot(output, 'output matches snapshot') }) t.test('config list --long', async t => { - const temp = t.testdir({ - global: { - npmrc: 'globalloaded=yes', - }, - project: { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: { '.npmrc': 'projectloaded=yes', }, - home: { + globalPrefixDir: { + etc: { + npmrc: 'globalloaded=yes', + }, + }, + homeDir: { '.npmrc': 'userloaded=yes', }, + config: { + long: true, + }, }) - const global = join(temp, 'global') - const project = join(temp, 'project') - const home = join(temp, 'home') - const sandbox = new Sandbox(t, { global, project, home }) - await sandbox.run('config', ['list', '--long']) + await npm.exec('config', ['list']) + + const output = joinedOutput() - t.matchSnapshot(sandbox.output, 'output matches snapshot') + t.match(output, 'projectloaded = "yes"') + t.match(output, 'globalloaded = "yes"') + t.match(output, 'userloaded = "yes"') + + t.matchSnapshot(output, 'output matches snapshot') }) t.test('config list --json', async t => { - const temp = t.testdir({ - global: { - npmrc: 'globalloaded=yes', - }, - project: { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: { '.npmrc': 'projectloaded=yes', }, - home: { + globalPrefixDir: { + etc: { + npmrc: 'globalloaded=yes', + }, + }, + homeDir: { '.npmrc': 'userloaded=yes', }, + config: { + json: true, + }, }) - const global = join(temp, 'global') - const project = join(temp, 'project') - const home = join(temp, 'home') - const sandbox = new Sandbox(t, { global, project, home }) - await sandbox.run('config', ['list', '--json']) + await npm.exec('config', ['list']) + + const output = joinedOutput() + + t.match(output, '"projectloaded": "yes",') + t.match(output, '"globalloaded": "yes",') + t.match(output, '"userloaded": "yes",') - t.matchSnapshot(sandbox.output, 'output matches snapshot') + t.matchSnapshot(output, 'output matches snapshot') }) t.test('config list with publishConfig', async t => { - const temp = t.testdir({ - project: { + const loadMockNpmWithPublishConfig = (t, opts) => loadMockNpm(t, { + prefixDir: { 'package.json': JSON.stringify({ publishConfig: { registry: 'https://some.registry', @@ -108,21 +163,43 @@ t.test('config list with publishConfig', async t => { }, }), }, + ...opts, }) - const project = join(temp, 'project') - const sandbox = new Sandbox(t, { project }) - await sandbox.run('config', ['list', '']) - await sandbox.run('config', ['list', '--global']) + t.test('local', async t => { + const { npm, joinedOutput } = await loadMockNpmWithPublishConfig(t) - t.matchSnapshot(sandbox.output, 'output matches snapshot') + await npm.exec('config', ['list']) + + const output = joinedOutput() + + t.match(output, 'registry = "https://some.registry"') + + t.matchSnapshot(output, 'output matches snapshot') + }) + + t.test('global', async t => { + const { npm, joinedOutput } = await loadMockNpmWithPublishConfig(t, { + config: { + global: true, + }, + }) + + await npm.exec('config', ['list']) + + const output = joinedOutput() + + t.notMatch(output, 'registry = "https://some.registry"') + + t.matchSnapshot(output, 'output matches snapshot') + }) }) t.test('config delete no args', async t => { - const sandbox = new Sandbox(t) + const { npm } = await loadMockNpm(t) await t.rejects( - sandbox.run('config', ['delete']), + npm.exec('config', ['delete']), { code: 'EUSAGE', }, @@ -132,14 +209,15 @@ t.test('config delete no args', async t => { t.test('config delete single key', async t => { // location defaults to user, so we work with a userconfig - const home = t.testdir({ - '.npmrc': 'access=public\nall=true', + const { npm, home } = await loadMockNpm(t, { + homeDir: { + '.npmrc': 'access=public\nall=true', + }, }) - const sandbox = new Sandbox(t, { home }) - await sandbox.run('config', ['delete', 'access']) + await npm.exec('config', ['delete', 'access']) - t.equal(sandbox.config.get('access'), null, 'acces should be defaulted') + t.equal(npm.config.get('access'), null, 'acces should be defaulted') const contents = await fs.readFile(join(home, '.npmrc'), { encoding: 'utf8' }) const rc = ini.parse(contents) @@ -147,15 +225,16 @@ t.test('config delete single key', async t => { }) t.test('config delete multiple keys', async t => { - const home = t.testdir({ - '.npmrc': 'access=public\nall=true\naudit=false', + const { npm, home } = await loadMockNpm(t, { + homeDir: { + '.npmrc': 'access=public\nall=true\naudit=false', + }, }) - const sandbox = new Sandbox(t, { home }) - await sandbox.run('config', ['delete', 'access', 'all']) + await npm.exec('config', ['delete', 'access', 'all']) - t.equal(sandbox.config.get('access'), null, 'access should be defaulted') - t.equal(sandbox.config.get('all'), false, 'all should be defaulted') + t.equal(npm.config.get('access'), null, 'access should be defaulted') + t.equal(npm.config.get('all'), false, 'all should be defaulted') const contents = await fs.readFile(join(home, '.npmrc'), { encoding: 'utf8' }) const rc = ini.parse(contents) @@ -164,76 +243,87 @@ t.test('config delete multiple keys', async t => { }) t.test('config delete key --location=global', async t => { - const global = t.testdir({ - npmrc: 'access=public\nall=true', + const { npm, globalPrefix } = await loadMockNpm(t, { + globalPrefixDir: { + etc: { + npmrc: 'access=public\nall=true', + }, + }, + config: { + location: 'global', + }, }) + await npm.exec('config', ['delete', 'access']) - const sandbox = new Sandbox(t, { global }) - await sandbox.run('config', ['delete', 'access', '--location=global']) + t.equal(npm.config.get('access', 'global'), undefined, 'access should be defaulted') - t.equal(sandbox.config.get('access', 'global'), undefined, 'access should be defaulted') - - const contents = await fs.readFile(join(global, 'npmrc'), { encoding: 'utf8' }) + const contents = await fs.readFile(join(globalPrefix, 'etc/npmrc'), { encoding: 'utf8' }) const rc = ini.parse(contents) t.not(rc.access, 'access is not set') }) t.test('config delete key --global', async t => { - const global = t.testdir({ - npmrc: 'access=public\nall=true', + const { npm, globalPrefix } = await loadMockNpm(t, { + globalPrefixDir: { + etc: { + npmrc: 'access=public\nall=true', + }, + }, + config: { + global: true, + }, }) - const sandbox = new Sandbox(t, { global }) - await sandbox.run('config', ['delete', 'access', '--global']) + await npm.exec('config', ['delete', 'access']) - t.equal(sandbox.config.get('access', 'global'), undefined, 'access should no longer be set') + t.equal(npm.config.get('access', 'global'), undefined, 'access should no longer be set') - const contents = await fs.readFile(join(global, 'npmrc'), { encoding: 'utf8' }) + const contents = await fs.readFile(join(globalPrefix, 'etc/npmrc'), { encoding: 'utf8' }) const rc = ini.parse(contents) t.not(rc.access, 'access is not set') }) t.test('config set invalid option', async t => { - const sandbox = new Sandbox(t) + const { npm } = await loadMockNpm(t) await t.rejects( - sandbox.run('config', ['set', 'nonexistantconfigoption', 'something']), + npm.exec('config', ['set', 'nonexistantconfigoption', 'something']), /not a valid npm option/ ) }) t.test('config set deprecated option', async t => { - const sandbox = new Sandbox(t) + const { npm } = await loadMockNpm(t) await t.rejects( - sandbox.run('config', ['set', 'shrinkwrap', 'true']), + npm.exec('config', ['set', 'shrinkwrap', 'true']), /deprecated/ ) }) t.test('config set nerf-darted option', async t => { - const sandbox = new Sandbox(t) - await sandbox.run('config', ['set', '//npm.pkg.github.com/:_authToken', '0xdeadbeef']) + const { npm } = await loadMockNpm(t) + await npm.exec('config', ['set', '//npm.pkg.github.com/:_authToken', '0xdeadbeef']) t.equal( - sandbox.config.get('//npm.pkg.github.com/:_authToken'), + npm.config.get('//npm.pkg.github.com/:_authToken'), '0xdeadbeef', 'nerf-darted config is set' ) }) t.test('config set scoped optoin', async t => { - const sandbox = new Sandbox(t) - await sandbox.run('config', ['set', '@npm:registry', 'https://registry.npmjs.org']) + const { npm } = await loadMockNpm(t) + await npm.exec('config', ['set', '@npm:registry', 'https://registry.npmjs.org']) t.equal( - sandbox.config.get('@npm:registry'), + npm.config.get('@npm:registry'), 'https://registry.npmjs.org', 'scoped config is set' ) }) t.test('config set no args', async t => { - const sandbox = new Sandbox(t) + const { npm } = await loadMockNpm(t) await t.rejects( - sandbox.run('config', ['set']), + npm.exec('config', ['set']), { code: 'EUSAGE', }, @@ -242,45 +332,45 @@ t.test('config set no args', async t => { }) t.test('config set key', async t => { - const home = t.testdir({ - '.npmrc': 'access=public', + const { npm, home } = await loadMockNpm(t, { + homeDir: { + '.npmrc': 'access=public', + }, }) - const sandbox = new Sandbox(t, { home }) + await npm.exec('config', ['set', 'access']) - await sandbox.run('config', ['set', 'access']) - - t.equal(sandbox.config.get('access'), null, 'set the value for access') + t.equal(npm.config.get('access'), null, 'set the value for access') await t.rejects(fs.stat(join(home, '.npmrc'), { encoding: 'utf8' }), 'removed empty config') }) t.test('config set key value', async t => { - const home = t.testdir({ - '.npmrc': 'access=public', + const { npm, home } = await loadMockNpm(t, { + homeDir: { + '.npmrc': 'access=public', + }, }) - const sandbox = new Sandbox(t, { home }) + await npm.exec('config', ['set', 'access', 'restricted']) - await sandbox.run('config', ['set', 'access', 'restricted']) - - t.equal(sandbox.config.get('access'), 'restricted', 'set the value for access') + t.equal(npm.config.get('access'), 'restricted', 'set the value for access') const contents = await fs.readFile(join(home, '.npmrc'), { encoding: 'utf8' }) const rc = ini.parse(contents) t.equal(rc.access, 'restricted', 'access is set to restricted') }) -t.test('config set key=value', async t => { - const home = t.testdir({ - '.npmrc': 'access=public', +t.test('config set key value with equals', async t => { + const { npm, home } = await loadMockNpm(t, { + homeDir: { + '.npmrc': 'access=public', + }, }) - const sandbox = new Sandbox(t, { home }) - - await sandbox.run('config', ['set', 'access=restricted']) + await npm.exec('config', ['set', 'access=restricted']) - t.equal(sandbox.config.get('access'), 'restricted', 'set the value for access') + t.equal(npm.config.get('access'), 'restricted', 'set the value for access') const contents = await fs.readFile(join(home, '.npmrc'), { encoding: 'utf8' }) const rc = ini.parse(contents) @@ -288,16 +378,17 @@ t.test('config set key=value', async t => { }) t.test('config set key1 value1 key2=value2 key3', async t => { - const home = t.testdir({ - '.npmrc': 'access=public\nall=true\naudit=true', + const { npm, home } = await loadMockNpm(t, { + homeDir: { + '.npmrc': 'access=public\nall=true\naudit=true', + }, }) - const sandbox = new Sandbox(t, { home }) - await sandbox.run('config', ['set', 'access', 'restricted', 'all=false', 'audit']) + await npm.exec('config', ['set', 'access', 'restricted', 'all=false', 'audit']) - t.equal(sandbox.config.get('access'), 'restricted', 'access was set') - t.equal(sandbox.config.get('all'), false, 'all was set') - t.equal(sandbox.config.get('audit'), true, 'audit was unset and restored to its default') + t.equal(npm.config.get('access'), 'restricted', 'access was set') + t.equal(npm.config.get('all'), false, 'all was set') + t.equal(npm.config.get('audit'), true, 'audit was unset and restored to its default') const contents = await fs.readFile(join(home, '.npmrc'), { encoding: 'utf8' }) const rc = ini.parse(contents) @@ -307,113 +398,120 @@ t.test('config set key1 value1 key2=value2 key3', async t => { }) t.test('config set invalid key logs warning', async t => { - const sandbox = new Sandbox(t) + const { npm, logs, home } = await loadMockNpm(t) // this doesn't reject, it only logs a warning - await sandbox.run('config', ['set', 'access=foo']) - t.match( - sandbox.logs.warn, - [['invalid config', 'access="foo"', `set in ${join(sandbox.home, '.npmrc')}`]], + await npm.exec('config', ['set', 'access=foo']) + t.equal(logs.warn[0], + `invalid config access="foo" set in ${join(home, '.npmrc')}`, 'logged warning' ) }) t.test('config set key=value --location=global', async t => { - const global = t.testdir({ - npmrc: 'access=public\nall=true', + const { npm, globalPrefix } = await loadMockNpm(t, { + globalPrefixDir: { + etc: { + npmrc: 'access=public\nall=true', + }, + }, + config: { + location: 'global', + }, }) - const sandbox = new Sandbox(t, { global }) - await sandbox.run('config', ['set', 'access=restricted', '--location=global']) + await npm.exec('config', ['set', 'access=restricted']) - t.equal(sandbox.config.get('access', 'global'), 'restricted', 'foo should be set') + t.equal(npm.config.get('access', 'global'), 'restricted', 'foo should be set') - const contents = await fs.readFile(join(global, 'npmrc'), { encoding: 'utf8' }) + const contents = await fs.readFile(join(globalPrefix, 'etc/npmrc'), { encoding: 'utf8' }) const rc = ini.parse(contents) t.equal(rc.access, 'restricted', 'access is set to restricted') }) t.test('config set key=value --global', async t => { - const global = t.testdir({ - npmrc: 'access=public\nall=true', + const { npm, globalPrefix } = await loadMockNpm(t, { + globalPrefixDir: { + etc: { + npmrc: 'access=public\nall=true', + }, + }, + config: { + global: true, + }, }) - const sandbox = new Sandbox(t, { global }) - await sandbox.run('config', ['set', 'access=restricted', '--global']) + await npm.exec('config', ['set', 'access=restricted']) - t.equal(sandbox.config.get('access', 'global'), 'restricted', 'access should be set') + t.equal(npm.config.get('access', 'global'), 'restricted', 'access should be set') - const contents = await fs.readFile(join(global, 'npmrc'), { encoding: 'utf8' }) + const contents = await fs.readFile(join(globalPrefix, 'etc/npmrc'), { encoding: 'utf8' }) const rc = ini.parse(contents) t.equal(rc.access, 'restricted', 'access is set to restricted') }) t.test('config get no args', async t => { - const sandbox = new Sandbox(t) + const { npm, joinedOutput, clearOutput } = await loadMockNpm(t) - await sandbox.run('config', ['get']) - const getOutput = sandbox.output + await npm.exec('config', ['get']) + const getOutput = joinedOutput() - sandbox.reset() - - await sandbox.run('config', ['list']) - const listOutput = sandbox.output + clearOutput() + await npm.exec('config', ['list']) + const listOutput = joinedOutput() t.equal(listOutput, getOutput, 'get with no args outputs list') }) t.test('config get single key', async t => { - const sandbox = new Sandbox(t) + const { npm, joinedOutput } = await loadMockNpm(t) - await sandbox.run('config', ['get', 'all']) - t.equal(sandbox.output, `${sandbox.config.get('all')}`, 'should get the value') + await npm.exec('config', ['get', 'all']) + t.equal(joinedOutput(), `${npm.config.get('all')}`, 'should get the value') }) t.test('config get multiple keys', async t => { - const sandbox = new Sandbox(t) + const { npm, joinedOutput } = await loadMockNpm(t) - await sandbox.run('config', ['get', 'yes', 'all']) - t.ok( - sandbox.output.includes(`yes=${sandbox.config.get('yes')}`), - 'outputs yes' - ) - t.ok( - sandbox.output.includes(`all=${sandbox.config.get('all')}`), - 'outputs all' - ) + await npm.exec('config', ['get', 'yes', 'all']) + t.equal(joinedOutput(), `yes=${npm.config.get('yes')}\nall=${npm.config.get('all')}`) }) t.test('config get private key', async t => { - const sandbox = new Sandbox(t) + const { npm } = await loadMockNpm(t) await t.rejects( - sandbox.run('config', ['get', '_authToken']), + npm.exec('config', ['get', '_authToken']), /_authToken option is protected/, 'rejects with protected string' ) await t.rejects( - sandbox.run('config', ['get', '//localhost:8080/:_password']), + npm.exec('config', ['get', '//localhost:8080/:_password']), /_password option is protected/, 'rejects with protected string' ) }) t.test('config edit', async t => { - const home = t.testdir({ - '.npmrc': 'foo=bar\nbar=baz', - }) - const EDITOR = 'vim' const editor = spawk.spawn(EDITOR).exit(0) - const sandbox = new Sandbox(t, { home, env: { EDITOR } }) - await sandbox.run('config', ['edit']) + const { npm, home } = await loadMockNpm(t, { + homeDir: { + '.npmrc': 'foo=bar\nbar=baz', + }, + config: { + editor: EDITOR, + }, + }) + + await npm.exec('config', ['edit']) t.ok(editor.called, 'editor was spawned') t.same( editor.calledWith.args, - [join(sandbox.home, '.npmrc')], + [join(home, '.npmrc')], 'editor opened the user config file' ) @@ -427,10 +525,14 @@ t.test('config edit - editor exits non-0', async t => { const EDITOR = 'vim' const editor = spawk.spawn(EDITOR).exit(1) - const sandbox = new Sandbox(t) - sandbox.process.env.EDITOR = EDITOR + const { npm, home } = await loadMockNpm(t, { + config: { + editor: EDITOR, + }, + }) + await t.rejects( - sandbox.run('config', ['edit']), + npm.exec('config', ['edit']), { message: 'editor process exited with code: 1', }, @@ -440,101 +542,102 @@ t.test('config edit - editor exits non-0', async t => { t.ok(editor.called, 'editor was spawned') t.same( editor.calledWith.args, - [join(sandbox.home, '.npmrc')], + [join(home, '.npmrc')], 'editor opened the user config file' ) }) t.test('config fix', (t) => { t.test('no problems', async (t) => { - const home = t.testdir({ - '.npmrc': '', + const { npm, joinedOutput } = await loadMockNpm(t, { + homeDir: { + '.npmrc': '', + }, }) - const sandbox = new Sandbox(t, { home }) - await sandbox.run('config', ['fix']) - t.equal(sandbox.output, '', 'printed nothing') + await npm.exec('config', ['fix']) + t.equal(joinedOutput(), '', 'printed nothing') }) t.test('repairs all configs by default', async (t) => { - const root = t.testdir({ - global: { - npmrc: '_authtoken=notatoken\n_authToken=afaketoken', + const { npm, home, globalPrefix, joinedOutput } = await loadMockNpm(t, { + globalPrefixDir: { + etc: { + npmrc: '_authtoken=notatoken\n_authToken=afaketoken', + }, }, - home: { + homeDir: { '.npmrc': '_authtoken=thisisinvalid\n_auth=beef', }, }) + const registry = `//registry.npmjs.org/` - const sandbox = new Sandbox(t, { - global: join(root, 'global'), - home: join(root, 'home'), - }) - await sandbox.run('config', ['fix']) + await npm.exec('config', ['fix']) // global config fixes - t.match(sandbox.output, '`_authtoken` deleted from global config', + t.match(joinedOutput(), '`_authtoken` deleted from global config', 'output has deleted global _authtoken') - t.match(sandbox.output, `\`_authToken\` renamed to \`${registry}:_authToken\` in global config`, + t.match(joinedOutput(), `\`_authToken\` renamed to \`${registry}:_authToken\` in global config`, 'output has renamed global _authToken') - t.not(sandbox.config.get('_authtoken', 'global'), '_authtoken is not set globally') - t.not(sandbox.config.get('_authToken', 'global'), '_authToken is not set globally') - t.equal(sandbox.config.get(`${registry}:_authToken`, 'global'), 'afaketoken', + t.not(npm.config.get('_authtoken', 'global'), '_authtoken is not set globally') + t.not(npm.config.get('_authToken', 'global'), '_authToken is not set globally') + t.equal(npm.config.get(`${registry}:_authToken`, 'global'), 'afaketoken', 'global _authToken was scoped') - const globalConfig = await fs.readFile(join(root, 'global', 'npmrc'), { encoding: 'utf8' }) + const globalConfig = await fs.readFile(join(globalPrefix, 'etc/npmrc'), { encoding: 'utf8' }) t.equal(globalConfig, `${registry}:_authToken=afaketoken\n`, 'global config was written') // user config fixes - t.match(sandbox.output, '`_authtoken` deleted from user config', + t.match(joinedOutput(), '`_authtoken` deleted from user config', 'output has deleted user _authtoken') - t.match(sandbox.output, `\`_auth\` renamed to \`${registry}:_auth\` in user config`, + t.match(joinedOutput(), `\`_auth\` renamed to \`${registry}:_auth\` in user config`, 'output has renamed user _auth') - t.not(sandbox.config.get('_authtoken', 'user'), '_authtoken is not set in user config') - t.not(sandbox.config.get('_auth'), '_auth is not set in user config') - t.equal(sandbox.config.get(`${registry}:_auth`, 'user'), 'beef', 'user _auth was scoped') - const userConfig = await fs.readFile(join(root, 'home', '.npmrc'), { encoding: 'utf8' }) + t.not(npm.config.get('_authtoken', 'user'), '_authtoken is not set in user config') + t.not(npm.config.get('_auth'), '_auth is not set in user config') + t.equal(npm.config.get(`${registry}:_auth`, 'user'), 'beef', 'user _auth was scoped') + const userConfig = await fs.readFile(join(home, '.npmrc'), { encoding: 'utf8' }) t.equal(userConfig, `${registry}:_auth=beef\n`, 'user config was written') }) t.test('repairs only the config specified by --location if asked', async (t) => { - const root = t.testdir({ - global: { - npmrc: '_authtoken=notatoken\n_authToken=afaketoken', + const { npm, home, globalPrefix, joinedOutput } = await loadMockNpm(t, { + globalPrefixDir: { + etc: { + npmrc: '_authtoken=notatoken\n_authToken=afaketoken', + }, }, - home: { + homeDir: { '.npmrc': '_authtoken=thisisinvalid\n_auth=beef', }, + config: { + location: 'user', + }, }) const registry = `//registry.npmjs.org/` - const sandbox = new Sandbox(t, { - global: join(root, 'global'), - home: join(root, 'home'), - }) - await sandbox.run('config', ['fix', '--location=user']) + await npm.exec('config', ['fix']) // global config should be untouched - t.notMatch(sandbox.output, '`_authtoken` deleted from global', + t.notMatch(joinedOutput(), '`_authtoken` deleted from global', 'output has deleted global _authtoken') - t.notMatch(sandbox.output, `\`_authToken\` renamed to \`${registry}:_authToken\` in global`, + t.notMatch(joinedOutput(), `\`_authToken\` renamed to \`${registry}:_authToken\` in global`, 'output has renamed global _authToken') - t.equal(sandbox.config.get('_authtoken', 'global'), 'notatoken', 'global _authtoken untouched') - t.equal(sandbox.config.get('_authToken', 'global'), 'afaketoken', 'global _authToken untouched') - t.not(sandbox.config.get(`${registry}:_authToken`, 'global'), 'global _authToken not scoped') - const globalConfig = await fs.readFile(join(root, 'global', 'npmrc'), { encoding: 'utf8' }) + t.equal(npm.config.get('_authtoken', 'global'), 'notatoken', 'global _authtoken untouched') + t.equal(npm.config.get('_authToken', 'global'), 'afaketoken', 'global _authToken untouched') + t.not(npm.config.get(`${registry}:_authToken`, 'global'), 'global _authToken not scoped') + const globalConfig = await fs.readFile(join(globalPrefix, 'etc/npmrc'), { encoding: 'utf8' }) t.equal(globalConfig, '_authtoken=notatoken\n_authToken=afaketoken', 'global config was not written') // user config fixes - t.match(sandbox.output, '`_authtoken` deleted from user', + t.match(joinedOutput(), '`_authtoken` deleted from user', 'output has deleted user _authtoken') - t.match(sandbox.output, `\`_auth\` renamed to \`${registry}:_auth\` in user`, + t.match(joinedOutput(), `\`_auth\` renamed to \`${registry}:_auth\` in user`, 'output has renamed user _auth') - t.not(sandbox.config.get('_authtoken', 'user'), '_authtoken is not set in user config') - t.not(sandbox.config.get('_auth', 'user'), '_auth is not set in user config') - t.equal(sandbox.config.get(`${registry}:_auth`, 'user'), 'beef', 'user _auth was scoped') - const userConfig = await fs.readFile(join(root, 'home', '.npmrc'), { encoding: 'utf8' }) + t.not(npm.config.get('_authtoken', 'user'), '_authtoken is not set in user config') + t.not(npm.config.get('_auth', 'user'), '_auth is not set in user config') + t.equal(npm.config.get(`${registry}:_auth`, 'user'), 'beef', 'user _auth was scoped') + const userConfig = await fs.readFile(join(home, '.npmrc'), { encoding: 'utf8' }) t.equal(userConfig, `${registry}:_auth=beef\n`, 'user config was written') }) @@ -542,15 +645,21 @@ t.test('config fix', (t) => { }) t.test('completion', async t => { - const sandbox = new Sandbox(t) - - let allKeys - const testComp = async (argv, expect) => { - t.match(await sandbox.complete('config', argv), expect, argv.join(' ')) - if (!allKeys) { - allKeys = Object.keys(sandbox.config.definitions) - } - sandbox.reset() + const { config, npm } = await loadMockNpm(t, { command: 'config' }) + + const allKeys = Object.keys(npm.config.definitions) + + const testComp = async (argv, expect, msg) => { + const options = Array.isArray(argv) ? { + conf: { + argv: { + remain: ['config', ...argv], + }, + }, + } : argv + options.conf.argv.remain.unshift('npm') + const res = await config.completion(options) + t.strictSame(res, expect, msg ?? argv.join(' ')) } await testComp([], ['get', 'set', 'delete', 'ls', 'rm', 'edit', 'fix', 'list']) @@ -564,10 +673,12 @@ t.test('completion', async t => { await testComp(['list'], []) await testComp(['ls'], []) - const getCommand = await sandbox.complete('get') - t.match(getCommand, allKeys, 'also works for just npm get') - sandbox.reset() + await testComp({ + conf: { argv: { remain: ['get'] } }, + }, allKeys, 'also works for just npm get') - const partial = await sandbox.complete('config', 'l') - t.match(partial, ['get', 'set', 'delete', 'ls', 'rm', 'edit'], 'and works on partials') + await testComp({ + partialWord: 'l', + conf: { argv: { remain: ['config'] } }, + }, ['get', 'set', 'delete', 'ls', 'rm', 'edit', 'fix'], 'and works on partials') }) diff --git a/deps/npm/test/lib/commands/dist-tag.js b/deps/npm/test/lib/commands/dist-tag.js index 918f658c6462aa..5de9acb1da81f5 100644 --- a/deps/npm/test/lib/commands/dist-tag.js +++ b/deps/npm/test/lib/commands/dist-tag.js @@ -88,12 +88,7 @@ const mockDist = async (t, { ...npmOpts } = {}) => { distTag: mock['dist-tag'], fetchOpts: () => fetchOpts, result: () => mock.joinedOutput(), - logs: () => { - const distLogs = mock.logs.filter(l => l[1].startsWith('dist-tag')) - return distLogs.map(([, ...parts]) => { - return parts.map(p => p.toString()).join(' ').trim() - }).join('\n').trim() - }, + joinedLogs: () => mock.logs.byTitle('dist-tag').join('\n').trim(), } } @@ -159,13 +154,13 @@ t.test('ls on named package', async t => { }) t.test('ls on missing package', async t => { - const { distTag, logs } = await mockDist(t) + const { distTag, joinedLogs } = await mockDist(t) await t.rejects( distTag.exec(['ls', 'foo']), distTag.usage ) t.matchSnapshot( - logs(), + joinedLogs(), 'should log no dist-tag found msg' ) }) @@ -245,8 +240,8 @@ t.test('workspaces', async t => { }) t.test('two args -- list, @scoped/pkg, logs a warning and ignores workspaces', async t => { - const { result, logs } = await mockWorkspaces(t, ['list', '@scoped/pkg']) - t.match(logs(), 'Ignoring workspaces for specified package', 'logs a warning') + const { result, joinedLogs } = await mockWorkspaces(t, ['list', '@scoped/pkg']) + t.match(joinedLogs(), 'Ignoring workspaces for specified package', 'logs a warning') t.matchSnapshot(result(), 'printed the expected output') }) @@ -266,7 +261,10 @@ t.test('workspaces', async t => { }, }) - t.match(logs(), 'dist-tag ls Couldn\'t get dist-tag data for workspace-d@*', 'logs the error') + const error = logs.error.byTitle('dist-tag ls')[0] + + t.match(error, 'Couldn\'t get dist-tag data for Result {') + t.match(error, `name: 'workspace-d',`) t.matchSnapshot(result(), 'printed the expected output') }) }) @@ -284,14 +282,14 @@ t.test('add new tag', async t => { }) t.test('add using valid semver range as name', async t => { - const { distTag, logs } = await mockDist(t) + const { distTag, joinedLogs } = await mockDist(t) await t.rejects( distTag.exec(['add', '@scoped/another@7.7.7', '1.0.0']), /Tag name must not be a valid SemVer range: 1.0.0/, 'should exit with semver range error' ) t.matchSnapshot( - logs(), + joinedLogs(), 'should return success msg' ) }) @@ -328,31 +326,31 @@ t.test('add invalid tag', async t => { }) t.test('set existing version', async t => { - const { distTag, logs } = await mockDist(t) + const { distTag, joinedLogs } = await mockDist(t) await distTag.exec(['set', '@scoped/another@0.6.0', 'b']) t.matchSnapshot( - logs(), + joinedLogs(), 'should log warn msg' ) }) t.test('remove existing tag', async t => { - const { distTag, result, logs, fetchOpts } = await mockDist(t) + const { distTag, result, joinedLogs, fetchOpts } = await mockDist(t) await distTag.exec(['rm', '@scoped/another', 'c']) const opts = fetchOpts() t.equal(opts.method, 'DELETE', 'should trigger request to remove tag') - t.matchSnapshot(logs(), 'should log remove info') + t.matchSnapshot(joinedLogs(), 'should log remove info') t.matchSnapshot(result(), 'should return success msg') }) t.test('remove non-existing tag', async t => { - const { distTag, logs } = await mockDist(t) + const { distTag, joinedLogs } = await mockDist(t) await t.rejects( distTag.exec(['rm', '@scoped/another', 'nonexistent']), /nonexistent is not a dist-tag on @scoped\/another/, 'should exit with error' ) - t.matchSnapshot(logs(), 'should log error msg') + t.matchSnapshot(joinedLogs(), 'should log error msg') }) t.test('remove missing pkg name', async t => { diff --git a/deps/npm/test/lib/commands/doctor.js b/deps/npm/test/lib/commands/doctor.js index 1682a6cccfa483..bf4ea46a918a17 100644 --- a/deps/npm/test/lib/commands/doctor.js +++ b/deps/npm/test/lib/commands/doctor.js @@ -1,5 +1,5 @@ const t = require('tap') -const fs = require('fs') +const fs = require('fs/promises') const path = require('path') const { load: loadMockNpm } = require('../../fixtures/mock-npm') @@ -11,6 +11,7 @@ const cleanCacheSha = (str) => str.replace(/content-v2\/sha512\/[^"]+/g, 'content-v2/sha512/{sha}') t.cleanSnapshot = p => cleanCacheSha(cleanDate(cleanCwd(p))) + .replace(/(doctor\s+at\s).*$/gm, '$1{STACK}') const npmManifest = (version) => { return { @@ -389,15 +390,15 @@ t.test('incorrect owner', async t => { const { joinedOutput, logs, npm } = await loadMockNpm(t, { mocks: { ...mocks, - fs: { + 'fs/promises': { ...fs, - lstat: (p, cb) => { - const stat = fs.lstatSync(p) + lstat: async (p) => { + const stat = await fs.lstat(p) if (p.endsWith('_cacache')) { stat.uid += 1 stat.gid += 1 } - return cb(null, stat) + return stat }, }, }, @@ -418,9 +419,9 @@ t.test('incorrect permissions', async t => { const { joinedOutput, logs, npm } = await loadMockNpm(t, { mocks: { ...mocks, - fs: { + 'fs/promises': { ...fs, - access: () => { + access: async () => { throw new Error('Test Error') }, }, @@ -442,9 +443,13 @@ t.test('error reading directory', async t => { const { joinedOutput, logs, npm } = await loadMockNpm(t, { mocks: { ...mocks, - fs: { + 'fs/promises': { ...fs, - readdir: () => { + readdir: async (s, ...args) => { + if (s.endsWith('_logs')) { + return fs.readdir(s, ...args) + } + // if (s.endsWith) throw new Error('Test Error') }, }, diff --git a/deps/npm/test/lib/commands/exec.js b/deps/npm/test/lib/commands/exec.js index 094cb7113d07a3..d0aa5f9a33974c 100644 --- a/deps/npm/test/lib/commands/exec.js +++ b/deps/npm/test/lib/commands/exec.js @@ -76,7 +76,7 @@ t.test('--prefix', async t => { }) // This is what `--prefix` does - npm.globalPrefix = npm.localPrefix + npm.config.globalPrefix = npm.config.localPrefix await registry.package({ manifest, diff --git a/deps/npm/test/lib/commands/help-search.js b/deps/npm/test/lib/commands/help-search.js index 8da725fad76924..354fb0291eb2f2 100644 --- a/deps/npm/test/lib/commands/help-search.js +++ b/deps/npm/test/lib/commands/help-search.js @@ -71,7 +71,7 @@ t.test('npm help-search long output with color', async t => { const chalk = await import('chalk').then(v => v.default) - const highlightedText = chalk.bgBlack.red('help-search') + const highlightedText = chalk.blue('help-search') t.equal( output.split('\n').some(line => line.includes(highlightedText)), true, diff --git a/deps/npm/test/lib/commands/hook.js b/deps/npm/test/lib/commands/hook.js index 382bc177e7001a..003dae647a35a2 100644 --- a/deps/npm/test/lib/commands/hook.js +++ b/deps/npm/test/lib/commands/hook.js @@ -1,6 +1,5 @@ const t = require('tap') const mockNpm = require('../../fixtures/mock-npm') -const { stripVTControlCharacters } = require('node:util') const mockHook = async (t, { hookResponse, ...npmOpts } = {}) => { const now = Date.now() @@ -31,6 +30,7 @@ const mockHook = async (t, { hookResponse, ...npmOpts } = {}) => { type: pkgTypes[name], endpoint: 'https://google.com', last_delivery: id % 2 === 0 ? now : undefined, + response_code: 200, })) }, rm: async (id, opts) => { @@ -85,7 +85,7 @@ t.test('npm hook add', async t => { }, 'provided the correct arguments to libnpmhook' ) - t.strictSame(outputs[0], ['+ semver -> https://google.com'], 'prints the correct output') + t.strictSame(outputs[0], '+ semver -> https://google.com', 'prints the correct output') }) t.test('npm hook add - correct owner hook output', async t => { @@ -102,7 +102,7 @@ t.test('npm hook add - correct owner hook output', async t => { }, 'provided the correct arguments to libnpmhook' ) - t.strictSame(outputs[0], ['+ ~npm -> https://google.com'], 'prints the correct output') + t.strictSame(outputs[0], '+ ~npm -> https://google.com', 'prints the correct output') }) t.test('npm hook add - correct scope hook output', async t => { @@ -119,7 +119,7 @@ t.test('npm hook add - correct scope hook output', async t => { }, 'provided the correct arguments to libnpmhook' ) - t.strictSame(outputs[0], ['+ @npmcli -> https://google.com'], 'prints the correct output') + t.strictSame(outputs[0], '+ @npmcli -> https://google.com', 'prints the correct output') }) t.test('npm hook add - unicode output', async t => { @@ -142,7 +142,7 @@ t.test('npm hook add - unicode output', async t => { }, 'provided the correct arguments to libnpmhook' ) - t.strictSame(outputs[0], ['+ semver ➜ https://google.com'], 'prints the correct output') + t.strictSame(outputs[0], '+ semver ➜ https://google.com', 'prints the correct output') }) t.test('npm hook add - json output', async t => { @@ -166,7 +166,7 @@ t.test('npm hook add - json output', async t => { 'provided the correct arguments to libnpmhook' ) t.strictSame( - JSON.parse(outputs[0][0]), + JSON.parse(outputs[0]), { id: 1, name: '@npmcli', @@ -199,12 +199,12 @@ t.test('npm hook add - parseable output', async t => { ) t.strictSame( - outputs[0][0].split(/\t/), + outputs[0].split(/\t/), ['id', 'name', 'type', 'endpoint'], 'prints the correct parseable output headers' ) t.strictSame( - outputs[1][0].split(/\t/), + outputs[1].split(/\t/), ['1', '@npmcli', 'scope', 'https://google.com'], 'prints the correct parseable values' ) @@ -243,11 +243,18 @@ t.test('npm hook ls', async t => { }, 'received the correct arguments' ) - t.equal(outputs[0][0], 'You have 3 hooks configured.', 'prints the correct header') - const out = stripVTControlCharacters(outputs[1][0]) - t.match(out, /semver.*https:\/\/google.com.*\n.*\n.*never triggered/, 'prints package hook') - t.match(out, /@npmcli.*https:\/\/google.com.*\n.*\n.*triggered just now/, 'prints scope hook') - t.match(out, /~npm.*https:\/\/google.com.*\n.*\n.*never triggered/, 'prints owner hook') + t.strictSame(outputs, [ + 'You have 3 hooks configured.', + 'Hook 1: semver', + 'Endpoint: https://google.com', + 'Never triggered\n', + 'Hook 2: @npmcli', + 'Endpoint: https://google.com', + 'Triggered just now, response code was "200"\n', + 'Hook 3: ~npm', + 'Endpoint: https://google.com', + 'Never triggered\n', + ]) }) t.test('npm hook ls, no results', async t => { @@ -266,7 +273,7 @@ t.test('npm hook ls, no results', async t => { }, 'received the correct arguments' ) - t.equal(outputs[0][0], "You don't have any hooks configured yet.", 'prints the correct result') + t.strictSame(outputs, [`You don't have any hooks configured yet.`]) }) t.test('npm hook ls, single result', async t => { @@ -292,9 +299,12 @@ t.test('npm hook ls, single result', async t => { }, 'received the correct arguments' ) - t.equal(outputs[0][0], 'You have one hook configured.', 'prints the correct header') - const out = stripVTControlCharacters(outputs[1][0]) - t.match(out, /semver.*https:\/\/google.com.*\n.*\n.*never triggered/, 'prints package hook') + t.strictSame(outputs, [ + 'You have 1 hook configured.', + 'Hook 1: semver', + 'Endpoint: https://google.com', + 'Never triggered\n', + ]) }) t.test('npm hook ls - json output', async t => { @@ -361,12 +371,12 @@ t.test('npm hook ls - parseable output', async t => { 'received the correct arguments' ) t.strictSame( - outputs.map(line => line[0].split(/\t/)), + outputs.map(line => line.split(/\t/)), [ - ['id', 'name', 'type', 'endpoint', 'last_delivery'], - ['1', 'semver', 'package', 'https://google.com', ''], - ['2', '@npmcli', 'scope', 'https://google.com', `${now}`], - ['3', 'npm', 'owner', 'https://google.com', ''], + ['id', 'name', 'type', 'endpoint', 'last_delivery', 'response_code'], + ['1', 'semver', 'package', 'https://google.com', '', '200'], + ['2', '@npmcli', 'scope', 'https://google.com', `${now}`, '200'], + ['3', 'npm', 'owner', 'https://google.com', '', '200'], ], 'prints the correct result' ) @@ -404,7 +414,7 @@ t.test('npm hook rm', async t => { }, 'received the correct arguments' ) - t.strictSame(outputs[0], ['- semver X https://google.com'], 'printed the correct output') + t.strictSame(outputs[0], '- semver X https://google.com', 'printed the correct output') }) t.test('npm hook rm - unicode output', async t => { @@ -425,7 +435,7 @@ t.test('npm hook rm - unicode output', async t => { }, 'received the correct arguments' ) - t.strictSame(outputs[0], ['- semver ✘ https://google.com'], 'printed the correct output') + t.strictSame(outputs[0], '- semver ✘ https://google.com', 'printed the correct output') }) t.test('npm hook rm - silent output', async t => { @@ -496,7 +506,7 @@ t.test('npm hook rm - parseable output', async t => { 'received the correct arguments' ) t.strictSame( - outputs.map(line => line[0].split(/\t/)), + outputs.map(line => line.split(/\t/)), [ ['id', 'name', 'type', 'endpoint'], ['1', 'semver', 'package', 'https://google.com'], @@ -520,7 +530,7 @@ t.test('npm hook update', async t => { }, 'received the correct arguments' ) - t.strictSame(outputs[0], ['+ semver -> https://google.com'], 'printed the correct output') + t.strictSame(outputs[0], '+ semver -> https://google.com', 'printed the correct output') }) t.test('npm hook update - unicode', async t => { @@ -543,7 +553,7 @@ t.test('npm hook update - unicode', async t => { }, 'received the correct arguments' ) - t.strictSame(outputs[0], ['+ semver ➜ https://google.com'], 'printed the correct output') + t.strictSame(outputs[0], '+ semver ➜ https://google.com', 'printed the correct output') }) t.test('npm hook update - json output', async t => { @@ -599,7 +609,7 @@ t.test('npm hook update - parseable output', async t => { 'received the correct arguments' ) t.strictSame( - outputs.map(line => line[0].split(/\t/)), + outputs.map(line => line.split(/\t/)), [ ['id', 'name', 'type', 'endpoint'], ['1', 'semver', 'package', 'https://google.com'], diff --git a/deps/npm/test/lib/commands/init.js b/deps/npm/test/lib/commands/init.js index cb708303f405a4..6dd23560bf8fa3 100644 --- a/deps/npm/test/lib/commands/init.js +++ b/deps/npm/test/lib/commands/init.js @@ -238,8 +238,7 @@ t.test('npm init cancel', async t => { await npm.exec('init', []) - t.equal(logs.warn[0][0], 'init', 'should have init title') - t.equal(logs.warn[0][1], 'canceled', 'should log canceled') + t.equal(logs.warn[0], 'init canceled', 'should have init title and canceled') }) t.test('npm init error', async t => { @@ -335,7 +334,7 @@ t.test('workspaces', async t => { 'should exit with missing package.json file error' ) - t.equal(logs.warn[0][0], 'Missing package.json. Try with `--include-workspace-root`.') + t.equal(logs.warn[0], 'init Missing package.json. Try with `--include-workspace-root`.') }) await t.test('bad package.json when settting workspace', async t => { diff --git a/deps/npm/test/lib/commands/login.js b/deps/npm/test/lib/commands/login.js index b42d3001ebb903..a55637f9e00e2f 100644 --- a/deps/npm/test/lib/commands/login.js +++ b/deps/npm/test/lib/commands/login.js @@ -1,12 +1,12 @@ const t = require('tap') -const fs = require('fs') -const path = require('path') +const fs = require('node:fs') +const path = require('node:path') +const stream = require('node:stream') const ini = require('ini') const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') const mockGlobals = require('@npmcli/mock-globals') const MockRegistry = require('@npmcli/mock-registry') -const stream = require('stream') const mockLogin = async (t, { stdin: stdinLines, registry: registryUrl, ...options } = {}) => { let stdin diff --git a/deps/npm/test/lib/commands/logout.js b/deps/npm/test/lib/commands/logout.js index 881003729ab4a1..3087c8bb1e61d1 100644 --- a/deps/npm/test/lib/commands/logout.js +++ b/deps/npm/test/lib/commands/logout.js @@ -18,8 +18,8 @@ t.test('token logout - user config', async t => { mockRegistry.logout('@foo/') await npm.exec('logout', []) t.equal( - logs.verbose.find(l => l[0] === 'logout')[1], - 'clearing token for https://registry.npmjs.org/', + logs.verbose.byTitle('logout')[0], + 'logout clearing token for https://registry.npmjs.org/', 'should log message with correct registry' ) const userRc = await fs.readFile(join(home, '.npmrc'), 'utf-8') @@ -45,8 +45,8 @@ t.test('token scoped logout - user config', async t => { mockRegistry.logout('@bar/') await npm.exec('logout', []) t.equal( - logs.verbose.find(l => l[0] === 'logout')[1], - 'clearing token for https://diff-registry.npmjs.com/', + logs.verbose.byTitle('logout')[0], + 'logout clearing token for https://diff-registry.npmjs.com/', 'should log message with correct registry' ) @@ -67,8 +67,8 @@ t.test('user/pass logout - user config', async t => { await npm.exec('logout', []) t.equal( - logs.verbose.find(l => l[0] === 'logout')[1], - 'clearing user credentials for https://registry.npmjs.org/', + logs.verbose.byTitle('logout')[0], + 'logout clearing user credentials for https://registry.npmjs.org/', 'should log message with correct registry' ) @@ -106,8 +106,8 @@ t.test('ignore invalid scoped registry config', async t => { await npm.exec('logout', []) t.equal( - logs.verbose.find(l => l[0] === 'logout')[1], - 'clearing token for https://registry.npmjs.org/', + logs.verbose.byTitle('logout')[0], + 'logout clearing token for https://registry.npmjs.org/', 'should log message with correct registry' ) const userRc = await fs.readFile(join(home, '.npmrc'), 'utf-8') @@ -135,8 +135,8 @@ t.test('token logout - project config', async t => { await npm.exec('logout', []) t.equal( - logs.verbose.find(l => l[0] === 'logout')[1], - 'clearing token for https://registry.npmjs.org/', + logs.verbose.byTitle('logout')[0], + 'logout clearing token for https://registry.npmjs.org/', 'should log message with correct registry' ) const userRc = await fs.readFile(join(home, '.npmrc'), 'utf-8') @@ -145,8 +145,8 @@ t.test('token logout - project config', async t => { 'other-config=true', ].join('\n'), 'leaves user config alone') t.equal( - logs.verbose.find(l => l[0] === 'logout')[1], - 'clearing token for https://registry.npmjs.org/', + logs.verbose.byTitle('logout')[0], + 'logout clearing token for https://registry.npmjs.org/', 'should log message with correct registry' ) const projectRc = await fs.readFile(join(prefix, '.npmrc'), 'utf-8') diff --git a/deps/npm/test/lib/commands/org.js b/deps/npm/test/lib/commands/org.js index 0c343f028d6dcf..7a1538d9c69e4a 100644 --- a/deps/npm/test/lib/commands/org.js +++ b/deps/npm/test/lib/commands/org.js @@ -1,6 +1,5 @@ const t = require('tap') const mockNpm = require('../../fixtures/mock-npm') -const { stripVTControlCharacters } = require('node:util') const mockOrg = async (t, { orgSize = 1, orgList = {}, ...npmOpts } = {}) => { let setArgs = null @@ -92,7 +91,7 @@ t.test('npm org add', async t => { 'received the correct arguments' ) t.equal( - outputs[0][0], + outputs[0], 'Added username as developer to orgname. You now have 1 member in this org.', 'printed the correct output' ) @@ -142,7 +141,7 @@ t.test('npm org add - more users', async t => { 'received the correct arguments' ) t.equal( - outputs[0][0], + outputs[0], 'Added username as developer to orgname. You now have 5 members in this org.', 'printed the correct output' ) @@ -198,7 +197,7 @@ t.test('npm org add - parseable output', async t => { 'received the correct arguments' ) t.strictSame( - outputs.map(line => line[0].split(/\t/)), + outputs.map(line => line.split(/\t/)), [ ['org', 'orgsize', 'user', 'role'], ['orgname', '1', 'username', 'developer'], @@ -251,7 +250,7 @@ t.test('npm org rm', async t => { 'libnpmorg.ls received the correct args' ) t.equal( - outputs[0][0], + outputs[0], 'Successfully removed username from orgname. You now have 0 members in this org.', 'printed the correct output' ) @@ -301,7 +300,7 @@ t.test('npm org rm - one user left', async t => { 'libnpmorg.ls received the correct args' ) t.equal( - outputs[0][0], + outputs[0], 'Successfully removed username from orgname. You now have 1 member in this org.', 'printed the correct output' ) @@ -370,7 +369,7 @@ t.test('npm org rm - parseable output', async t => { 'libnpmorg.ls received the correct args' ) t.strictSame( - outputs.map(line => line[0].split(/\t/)), + outputs.map(line => line.split(/\t/)), [ ['user', 'org', 'userCount', 'deleted'], ['username', 'orgname', '0', 'true'], @@ -427,10 +426,11 @@ t.test('npm org ls', async t => { }, 'receieved the correct args' ) - const out = stripVTControlCharacters(outputs[0][0]) - t.match(out, /one.*developer/, 'contains the developer member') - t.match(out, /two.*admin/, 'contains the admin member') - t.match(out, /three.*owner/, 'contains the owner member') + t.strictSame(outputs, [ + 'one - developer', + 'three - owner', + 'two - admin', + ]) }) t.test('npm org ls - user filter', async t => { @@ -452,9 +452,9 @@ t.test('npm org ls - user filter', async t => { }, 'receieved the correct args' ) - const out = stripVTControlCharacters(outputs[0][0]) - t.match(out, /username.*admin/, 'contains the filtered member') - t.notMatch(out, /missing.*admin/, 'does not contain other members') + t.strictSame(outputs, [ + 'username - admin', + ]) }) t.test('npm org ls - user filter, missing user', async t => { @@ -475,9 +475,7 @@ t.test('npm org ls - user filter, missing user', async t => { }, 'receieved the correct args' ) - const out = stripVTControlCharacters(outputs[0][0]) - t.notMatch(out, /username/, 'does not contain the requested member') - t.notMatch(out, /missing.*admin/, 'does not contain other members') + t.strictSame(outputs, []) }) t.test('npm org ls - no org', async t => { @@ -533,7 +531,7 @@ t.test('npm org ls - parseable output', async t => { 'receieved the correct args' ) t.strictSame( - outputs.map(line => line[0].split(/\t/)), + outputs.map(line => line.split(/\t/)), [ ['user', 'role'], ['one', 'developer'], diff --git a/deps/npm/test/lib/commands/owner.js b/deps/npm/test/lib/commands/owner.js index 9329e8985e60c0..ec774d16470484 100644 --- a/deps/npm/test/lib/commands/owner.js +++ b/deps/npm/test/lib/commands/owner.js @@ -123,7 +123,7 @@ t.test('owner ls fails to retrieve packument', async t => { }) 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.match(logs.error.byTitle('owner ls'), [`owner ls Couldn't get owner data @npmcli/test-package`]) }) t.test('owner ls ', async t => { @@ -240,8 +240,8 @@ t.test('owner add already an owner', async t => { await npm.exec('owner', ['add', username, packageName]) t.equal(joinedOutput(), '') t.match( - logs.info, - [['owner add', 'Already a package owner: test-user-a ']] + logs.info.byTitle('owner add'), + [`Already a package owner: test-user-a `] ) }) @@ -256,7 +256,7 @@ t.test('owner add fails to retrieve user', async t => { }) 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.match(logs.error.byTitle('owner mutate'), [`Error getting user data for ${username}`]) }) t.test('owner add fails to PUT updates', async t => { @@ -380,7 +380,7 @@ t.test('owner rm not a current owner', async t => { registry.couchuser({ username }) await registry.package({ manifest }) await npm.exec('owner', ['rm', username, packageName]) - t.match(logs.info, [['owner rm', `Not a package owner: ${username}`]]) + t.match(logs.info.byTitle('owner rm'), [`Not a package owner: ${username}`]) }) t.test('owner rm cwd package', async t => { diff --git a/deps/npm/test/lib/commands/pack.js b/deps/npm/test/lib/commands/pack.js index baec163c7b34d0..3ea67c78d996a3 100644 --- a/deps/npm/test/lib/commands/pack.js +++ b/deps/npm/test/lib/commands/pack.js @@ -17,8 +17,8 @@ t.test('should pack current directory with no arguments', async t => { }) await npm.exec('pack', []) const filename = 'test-package-1.0.0.tgz' - t.strictSame(outputs, [[filename]]) - t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents') + t.strictSame(outputs, [filename]) + t.matchSnapshot(logs.notice, 'logs pack contents') t.ok(fs.statSync(path.resolve(npm.prefix, filename))) }) @@ -35,7 +35,7 @@ t.test('follows pack-destination config', async t => { }) await npm.exec('pack', []) const filename = 'test-package-1.0.0.tgz' - t.strictSame(outputs, [[filename]]) + t.strictSame(outputs, [filename]) t.ok(fs.statSync(path.resolve(npm.prefix, 'tar-destination', filename))) }) @@ -50,7 +50,7 @@ t.test('should pack given directory for scoped package', async t => { }) await npm.exec('pack', []) const filename = 'npm-test-package-1.0.0.tgz' - t.strictSame(outputs, [[filename]]) + t.strictSame(outputs, [filename]) t.ok(fs.statSync(path.resolve(npm.prefix, filename))) }) @@ -67,16 +67,19 @@ t.test('should log output as valid json', async t => { await npm.exec('pack', []) const filename = 'test-package-1.0.0.tgz' t.matchSnapshot(outputs.map(JSON.parse), 'outputs as json') - t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents') + t.matchSnapshot(logs.notice, 'logs pack contents') t.ok(fs.statSync(path.resolve(npm.prefix, filename))) }) t.test('should log scoped package output as valid json', async t => { - const { npm, outputs, logs } = await loadMockNpm(t, { + const { npm, outputs, outputErrors, logs } = await loadMockNpm(t, { prefixDir: { 'package.json': JSON.stringify({ name: '@myscope/test-package', version: '1.0.0', + scripts: { + prepack: 'echo prepack!', + }, }), }, config: { json: true }, @@ -84,7 +87,8 @@ t.test('should log scoped package output as valid json', async t => { await npm.exec('pack', []) const filename = 'myscope-test-package-1.0.0.tgz' t.matchSnapshot(outputs.map(JSON.parse), 'outputs as json') - t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents') + t.matchSnapshot(outputErrors, 'stderr has banners') + t.matchSnapshot(logs.notice, 'logs pack contents') t.ok(fs.statSync(path.resolve(npm.prefix, filename))) }) @@ -100,8 +104,8 @@ t.test('dry run', async t => { }) await npm.exec('pack', []) const filename = 'test-package-1.0.0.tgz' - t.strictSame(outputs, [[filename]]) - t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents') + t.strictSame(outputs, [filename]) + t.matchSnapshot(logs.notice, 'logs pack contents') t.throws(() => fs.statSync(path.resolve(npm.prefix, filename))) }) @@ -121,29 +125,18 @@ t.test('foreground-scripts defaults to true', async t => { config: { 'dry-run': true }, }) - /* eslint no-console: 0 */ - // TODO: replace this with `const results = t.intercept(console, 'log')` - const log = console.log - t.teardown(() => { - console.log = log - }) - const caughtLogs = [] - console.log = (...args) => { - caughtLogs.push(args) - } - // end TODO - await npm.exec('pack', []) const filename = 'test-fg-scripts-0.0.0.tgz' - t.same( - caughtLogs, + t.strictSame( + outputs, [ - ['\n> test-fg-scripts@0.0.0 prepack\n> echo prepack!\n'], - ['\n> test-fg-scripts@0.0.0 postpack\n> echo postpack!\n'], + '\n> test-fg-scripts@0.0.0 prepack\n> echo prepack!\n', + '\n> test-fg-scripts@0.0.0 postpack\n> echo postpack!\n', + filename, ], - 'prepack and postpack log to stdout') - t.strictSame(outputs, [[filename]]) - t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents') + 'prepack and postpack log to stdout' + ) + t.matchSnapshot(logs.notice, 'logs pack contents') t.throws(() => fs.statSync(path.resolve(npm.prefix, filename))) }) @@ -163,26 +156,11 @@ t.test('foreground-scripts can still be set to false', async t => { config: { 'dry-run': true, 'foreground-scripts': false }, }) - /* eslint no-console: 0 */ - // TODO: replace this with `const results = t.intercept(console, 'log')` - const log = console.log - t.teardown(() => { - console.log = log - }) - const caughtLogs = [] - console.log = (...args) => { - caughtLogs.push(args) - } - // end TODO - await npm.exec('pack', []) const filename = 'test-fg-scripts-0.0.0.tgz' - t.same( - caughtLogs, - [], - 'prepack and postpack do not log to stdout') - t.strictSame(outputs, [[filename]]) - t.matchSnapshot(logs.notice.map(([, m]) => m), 'logs pack contents') + + t.strictSame(outputs, [filename], 'prepack and postpack do not log to stdout') + t.matchSnapshot(logs.notice, 'logs pack contents') t.throws(() => fs.statSync(path.resolve(npm.prefix, filename))) }) @@ -235,24 +213,24 @@ t.test('workspaces', async t => { t.test('all workspaces', async t => { const { npm, outputs } = await loadWorkspaces(t) await npm.exec('pack', []) - t.strictSame(outputs, [['workspace-a-1.0.0.tgz'], ['workspace-b-1.0.0.tgz']]) + t.strictSame(outputs, ['workspace-a-1.0.0.tgz', 'workspace-b-1.0.0.tgz']) }) t.test('all workspaces, `.` first arg', async t => { const { npm, outputs } = await loadWorkspaces(t) await npm.exec('pack', ['.']) - t.strictSame(outputs, [['workspace-a-1.0.0.tgz'], ['workspace-b-1.0.0.tgz']]) + t.strictSame(outputs, ['workspace-a-1.0.0.tgz', 'workspace-b-1.0.0.tgz']) }) t.test('one workspace', async t => { const { npm, outputs } = await loadWorkspaces(t) await npm.exec('pack', ['workspace-a']) - t.strictSame(outputs, [['workspace-a-1.0.0.tgz']]) + t.strictSame(outputs, ['workspace-a-1.0.0.tgz']) }) t.test('specific package', async t => { const { npm, outputs } = await loadWorkspaces(t) await npm.exec('pack', [npm.prefix]) - t.strictSame(outputs, [['workspaces-test-1.0.0.tgz']]) + t.strictSame(outputs, ['workspaces-test-1.0.0.tgz']) }) }) diff --git a/deps/npm/test/lib/commands/ping.js b/deps/npm/test/lib/commands/ping.js index 77201955ff2a8b..7f90ea394f9aeb 100644 --- a/deps/npm/test/lib/commands/ping.js +++ b/deps/npm/test/lib/commands/ping.js @@ -10,7 +10,10 @@ t.test('no details', async t => { }) registry.ping() await npm.exec('ping', []) - t.match(logs.notice, [['PING', 'https://registry.npmjs.org/'], ['PONG', /[0-9]+ms/]]) + t.match(logs.notice, [ + 'PING https://registry.npmjs.org/', + /PONG [0-9]+ms/, + ]) t.equal(joinedOutput(), '') }) @@ -20,12 +23,12 @@ t.test('with details', async t => { tap: t, registry: npm.config.get('registry'), }) - registry.ping({ body: { test: true } }) + registry.ping({ body: { test: true, test2: true } }) await npm.exec('ping', []) t.match(logs.notice, [ - ['PING', 'https://registry.npmjs.org/'], - ['PONG', /[0-9]+ms/], - ['PONG', '{\n "test": true\n}'], + `PING https://registry.npmjs.org/`, + /PONG [0-9]+ms/, + `PONG {\nPONG "test": true,\nPONG "test2": true\nPONG }`, ]) t.match(joinedOutput(), '') }) @@ -40,7 +43,10 @@ t.test('valid json', async t => { }) registry.ping() await npm.exec('ping', []) - t.match(logs.notice, [['PING', 'https://registry.npmjs.org/'], ['PONG', /[0-9]+ms/]]) + t.match(logs.notice, [ + 'PING https://registry.npmjs.org/', + /PONG [0-9]+ms/, + ]) t.match(JSON.parse(joinedOutput()), { registry: npm.config.get('registry'), time: /[0-9]+/, @@ -58,7 +64,10 @@ t.test('invalid json', async t => { }) registry.ping({ body: '{not: real"json]' }) await npm.exec('ping', []) - t.match(logs.notice, [['PING', 'https://registry.npmjs.org/'], ['PONG', /[0-9]+ms/]]) + t.match(logs.notice, [ + 'PING https://registry.npmjs.org/', + /PONG [0-9]+ms/, + ]) t.match(JSON.parse(joinedOutput()), { registry: npm.config.get('registry'), time: /[0-9]+/, diff --git a/deps/npm/test/lib/commands/profile.js b/deps/npm/test/lib/commands/profile.js index 784523f7ccd8ad..8bbffd1675d07f 100644 --- a/deps/npm/test/lib/commands/profile.js +++ b/deps/npm/test/lib/commands/profile.js @@ -9,13 +9,6 @@ const mockProfile = async (t, { npmProfile, readUserInfo, qrcode, config, ...opt async createToken () {}, }, 'qrcode-terminal': qrcode || { generate: (url, cb) => cb() }, - 'cli-table3': class extends Array { - toString () { - return this.filter(Boolean) - .map(i => [...Object.entries(i)].map(v => v.join(': '))) - .join('\n') - } - }, '{LIB}/utils/read-user-info.js': readUserInfo || { async password () {}, async otp () {}, @@ -96,16 +89,6 @@ t.test('profile get no args', async t => { t.matchSnapshot(result(), 'should output all profile info as parseable result') }) - t.test('--color', async t => { - const { profile, result } = await mockProfile(t, { - npmProfile: defaultNpmProfile, - config: { color: 'always' }, - }) - - await profile.exec(['get']) - t.matchSnapshot(result(), 'should output all profile info with color result') - }) - t.test('no tfa enabled', async t => { const npmProfile = { async get () { @@ -473,8 +456,8 @@ t.test('profile set ', async t => { await profile.exec(['set', 'password']) t.equal( - logs.warn[0][1], - 'Passwords do not match, please try again.', + logs.warn.byTitle('profile')[0], + 'profile Passwords do not match, please try again.', 'should log password mismatch message' ) @@ -557,7 +540,7 @@ t.test('enable-2fa', async t => { t.test('from basic username/password auth', async t => { const npmProfile = { - async createToken (pass) { + async createToken () { return {} }, } @@ -604,7 +587,7 @@ t.test('enable-2fa', async t => { async get () { return userProfile }, - async set (newProfile, conf) { + async set (newProfile) { t.match( newProfile, { @@ -676,7 +659,7 @@ t.test('enable-2fa', async t => { }, } }, - async set (newProfile, conf) { + async set (newProfile) { setCount++ // when profile response shows that 2fa is pending the @@ -764,7 +747,7 @@ t.test('enable-2fa', async t => { }, } }, - async set (newProfile, conf) { + async set () { return { ...userProfile, tfa: 'http://foo?secret=1234', @@ -776,7 +759,7 @@ t.test('enable-2fa', async t => { async password () { return 'password1234' }, - async otp (label) { + async otp () { return '123456' }, } @@ -803,7 +786,7 @@ t.test('enable-2fa', async t => { async get () { return userProfile }, - async set (newProfile, conf) { + async set () { return { ...userProfile, tfa: null, @@ -826,7 +809,7 @@ t.test('enable-2fa', async t => { config: { otp: '123456' }, }) - npm.config.getCredentialsByURI = reg => { + npm.config.getCredentialsByURI = () => { return { token: 'token' } } @@ -847,7 +830,7 @@ t.test('enable-2fa', async t => { tfa: undefined, } }, - async set (newProfile, conf) { + async set () { return { ...userProfile, tfa: null, @@ -869,7 +852,7 @@ t.test('enable-2fa', async t => { readUserInfo, }) - npm.config.getCredentialsByURI = reg => { + npm.config.getCredentialsByURI = () => { return { token: 'token' } } @@ -890,7 +873,7 @@ t.test('enable-2fa', async t => { tfa: undefined, } }, - async set (newProfile, conf) { + async set () { return { ...userProfile, tfa: null, @@ -912,7 +895,7 @@ t.test('enable-2fa', async t => { readUserInfo, }) - npm.config.getCredentialsByURI = reg => { + npm.config.getCredentialsByURI = () => { return { token: 'token' } } @@ -950,7 +933,7 @@ t.test('disable-2fa', async t => { async get () { return userProfile }, - async set (newProfile, conf) { + async set (newProfile) { t.same( newProfile, { @@ -1031,7 +1014,7 @@ t.test('disable-2fa', async t => { async get () { return userProfile }, - async set (newProfile, conf) { + async set (newProfile) { t.same( newProfile, { @@ -1049,7 +1032,7 @@ t.test('disable-2fa', async t => { async password () { return 'password1234' }, - async otp (label) { + async otp () { throw new Error('should not ask for otp') }, } diff --git a/deps/npm/test/lib/commands/publish.js b/deps/npm/test/lib/commands/publish.js index 751cd97d8acf6e..85a66d88b8b340 100644 --- a/deps/npm/test/lib/commands/publish.js +++ b/deps/npm/test/lib/commands/publish.js @@ -83,6 +83,8 @@ t.test('re-loads publishConfig.registry if added during script process', async t const { joinedOutput, npm } = await loadMockNpm(t, { config: { [`${alternateRegistry.slice(6)}/:_authToken`]: 'test-other-token', + // Keep output from leaking into tap logs for readability + 'foreground-scripts': false, }, prefixDir: { 'package.json': JSON.stringify({ @@ -136,6 +138,8 @@ t.test('prioritize CLI flags over publishConfig', async t => { const { joinedOutput, npm } = await loadMockNpm(t, { config: { [`${alternateRegistry.slice(6)}/:_authToken`]: 'test-other-token', + // Keep output from leaking into tap logs for readability + 'foreground-scripts': false, }, prefixDir: { 'package.json': JSON.stringify({ @@ -220,7 +224,7 @@ t.test('dry-run', async t => { }) t.test('foreground-scripts defaults to true', async t => { - const { joinedOutput, npm, logs } = await loadMockNpm(t, { + const { outputs, npm, logs } = await loadMockNpm(t, { config: { 'dry-run': true, ...auth, @@ -238,33 +242,22 @@ t.test('foreground-scripts defaults to true', async t => { }, }) - /* eslint no-console: 0 */ - // TODO: replace this with `const results = t.intercept(console, 'log')` - const log = console.log - t.teardown(() => { - console.log = log - }) - const caughtLogs = [] - console.log = (...args) => { - caughtLogs.push(args) - } - // end TODO - await npm.exec('publish', []) - t.equal(joinedOutput(), `+ test-fg-scripts@0.0.0`) + t.matchSnapshot(logs.notice) - t.same( - caughtLogs, + t.strictSame( + outputs, [ - ['\n> test-fg-scripts@0.0.0 prepack\n> echo prepack!\n'], - ['\n> test-fg-scripts@0.0.0 postpack\n> echo postpack!\n'], + '\n> test-fg-scripts@0.0.0 prepack\n> echo prepack!\n', + '\n> test-fg-scripts@0.0.0 postpack\n> echo postpack!\n', + `+ test-fg-scripts@0.0.0`, ], 'prepack and postpack log to stdout') }) t.test('foreground-scripts can still be set to false', async t => { - const { joinedOutput, npm, logs } = await loadMockNpm(t, { + const { outputs, npm, logs } = await loadMockNpm(t, { config: { 'dry-run': true, 'foreground-scripts': false, @@ -283,25 +276,13 @@ t.test('foreground-scripts can still be set to false', async t => { }, }) - /* eslint no-console: 0 */ - // TODO: replace this with `const results = t.intercept(console, 'log')` - const log = console.log - t.teardown(() => { - console.log = log - }) - const caughtLogs = [] - console.log = (...args) => { - caughtLogs.push(args) - } - // end TODO - await npm.exec('publish', []) - t.equal(joinedOutput(), `+ test-fg-scripts@0.0.0`) + t.matchSnapshot(logs.notice) - t.same( - caughtLogs, - [], + t.strictSame( + outputs, + [`+ test-fg-scripts@0.0.0`], 'prepack and postpack do not log to stdout') }) @@ -871,6 +852,7 @@ t.test('manifest', async t => { const { npm } = await loadMockNpm(t, { config: { ...auth, + 'foreground-scripts': false, }, chdir: () => root, mocks: { diff --git a/deps/npm/test/lib/commands/query.js b/deps/npm/test/lib/commands/query.js index 5292c50e1d365b..0907a9d0f4206f 100644 --- a/deps/npm/test/lib/commands/query.js +++ b/deps/npm/test/lib/commands/query.js @@ -258,7 +258,7 @@ t.test('expect entries', t => { npm.config.set('expect-results', false) await npm.exec('query', ['#a']) t.not(joinedOutput(), '[]', 'has entries') - t.same(logs.warn, [['query', 'Expected no results, got 1']]) + t.same(logs.warn.byTitle('query'), ['query Expected no results, got 1']) t.ok(process.exitCode, 'exits with code') }) t.test('false, no entries', async t => { @@ -286,7 +286,7 @@ t.test('expect entries', t => { npm.config.set('expect-results', true) await npm.exec('query', ['#b']) t.equal(joinedOutput(), '[]', 'does not have entries') - t.same(logs.warn, [['query', 'Expected results, got 0']]) + t.same(logs.warn.byTitle('query'), ['query Expected results, got 0']) t.ok(process.exitCode, 'exits with code') }) t.test('count, matches', async t => { @@ -305,7 +305,7 @@ t.test('expect entries', t => { npm.config.set('expect-result-count', 1) await npm.exec('query', ['#b']) t.equal(joinedOutput(), '[]', 'does not have entries') - t.same(logs.warn, [['query', 'Expected 1 result, got 0']]) + t.same(logs.warn.byTitle('query'), ['query Expected 1 result, got 0']) t.ok(process.exitCode, 'exits with code') }) t.test('count 3, does not match', async t => { @@ -315,7 +315,7 @@ t.test('expect entries', t => { npm.config.set('expect-result-count', 3) await npm.exec('query', ['#b']) t.equal(joinedOutput(), '[]', 'does not have entries') - t.same(logs.warn, [['query', 'Expected 3 results, got 0']]) + t.same(logs.warn.byTitle('query'), ['query Expected 3 results, got 0']) t.ok(process.exitCode, 'exits with code') }) t.end() diff --git a/deps/npm/test/lib/commands/run-script.js b/deps/npm/test/lib/commands/run-script.js index 24f51400e8dfc3..c5bb2b488c053d 100644 --- a/deps/npm/test/lib/commands/run-script.js +++ b/deps/npm/test/lib/commands/run-script.js @@ -30,7 +30,7 @@ const mockRs = async (t, { windows = false, runScript, ...opts } = {}) => { ...mock, RUN_SCRIPTS: () => RUN_SCRIPTS, runScript: mock['run-script'], - cleanLogs: () => mock.logs.error.flat().map(v => v.toString()).map(cleanCwd), + cleanLogs: () => mock.logs.error.map(cleanCwd), } } @@ -347,7 +347,6 @@ t.test('skip pre/post hooks when using ignoreScripts', async t => { env: 'env', }, }, - banner: true, event: 'env', }, ]) @@ -388,7 +387,6 @@ t.test('run silent', async t => { }, }, event: 'env', - banner: false, }, { event: 'postenv', @@ -428,14 +426,14 @@ t.test('list scripts', async t => { t.strictSame( output, [ - ['Lifecycle scripts included in x@1.2.3:'], - [' test\n exit 2'], - [' start\n node server.js'], - [' stop\n node kill-server.js'], - ['\navailable via `npm run-script`:'], - [' preenv\n echo before the env'], - [' postenv\n echo after the env'], - [''], + 'Lifecycle scripts included in x@1.2.3:', + ' test\n exit 2', + ' start\n node server.js', + ' stop\n node kill-server.js', + '\navailable via `npm run-script`:', + ' preenv\n echo before the env', + ' postenv\n echo after the env', + '', ], 'basic report' ) @@ -447,17 +445,17 @@ t.test('list scripts', async t => { }) t.test('warn json', async t => { const outputs = await mockList(t, { json: true }) - t.strictSame(outputs, [[JSON.stringify(scripts, 0, 2)]], 'json report') + t.strictSame(outputs, [JSON.stringify(scripts, 0, 2)], 'json report') }) t.test('parseable', async t => { const outputs = await mockList(t, { parseable: true }) t.strictSame(outputs, [ - ['test:exit 2'], - ['start:node server.js'], - ['stop:node kill-server.js'], - ['preenv:echo before the env'], - ['postenv:echo after the env'], + 'test:exit 2', + 'start:node server.js', + 'stop:node kill-server.js', + 'preenv:echo before the env', + 'postenv:echo after the env', ]) }) }) @@ -489,9 +487,9 @@ t.test('list scripts, only commands', async t => { await runScript.exec([]) t.strictSame(outputs, [ - ['Lifecycle scripts included in x@1.2.3:'], - [' preversion\n echo doing the version dance'], - [''], + 'Lifecycle scripts included in x@1.2.3:', + ' preversion\n echo doing the version dance', + '', ]) }) @@ -508,9 +506,9 @@ t.test('list scripts, only non-commands', async t => { await runScript.exec([]) t.strictSame(outputs, [ - ['Scripts available in x@1.2.3 via `npm run-script`:'], - [' glorp\n echo doing the glerp glop'], - [''], + 'Scripts available in x@1.2.3 via `npm run-script`:', + ' glorp\n echo doing the glerp glop', + '', ]) }) @@ -594,113 +592,109 @@ t.test('workspaces', async t => { t.test('list all scripts', async t => { const { outputs } = await mockWorkspaces(t) t.strictSame(outputs, [ - ['Scripts available in a@1.0.0 via `npm run-script`:'], - [' glorp\n echo a doing the glerp glop'], - [''], - ['Scripts available in b@2.0.0 via `npm run-script`:'], - [' glorp\n echo b doing the glerp glop'], - [''], - ['Lifecycle scripts included in c@1.0.0:'], - [' test\n exit 0'], - [' posttest\n echo posttest'], - ['\navailable via `npm run-script`:'], - [' lorem\n echo c lorem'], - [''], - ['Lifecycle scripts included in d@1.0.0:'], - [' test\n exit 0'], - [' posttest\n echo posttest'], - [''], - ['Lifecycle scripts included in e:'], - [' test\n exit 0'], - [' start\n echo start something'], - [''], + 'Scripts available in a@1.0.0 via `npm run-script`:', + ' glorp\n echo a doing the glerp glop', + '', + 'Scripts available in b@2.0.0 via `npm run-script`:', + ' glorp\n echo b doing the glerp glop', + '', + 'Lifecycle scripts included in c@1.0.0:', + ' test\n exit 0', + ' posttest\n echo posttest', + '\navailable via `npm run-script`:', + ' lorem\n echo c lorem', + '', + 'Lifecycle scripts included in d@1.0.0:', + ' test\n exit 0', + ' posttest\n echo posttest', + '', + 'Lifecycle scripts included in e:', + ' test\n exit 0', + ' start\n echo start something', + '', ]) }) t.test('list regular scripts, filtered by name', async t => { const { outputs } = await mockWorkspaces(t, { workspaces: ['a', 'b'] }) t.strictSame(outputs, [ - ['Scripts available in a@1.0.0 via `npm run-script`:'], - [' glorp\n echo a doing the glerp glop'], - [''], - ['Scripts available in b@2.0.0 via `npm run-script`:'], - [' glorp\n echo b doing the glerp glop'], - [''], + 'Scripts available in a@1.0.0 via `npm run-script`:', + ' glorp\n echo a doing the glerp glop', + '', + 'Scripts available in b@2.0.0 via `npm run-script`:', + ' glorp\n echo b doing the glerp glop', + '', ]) }) t.test('list regular scripts, filtered by path', async t => { const { outputs } = await mockWorkspaces(t, { workspaces: ['./packages/a'] }) t.strictSame(outputs, [ - ['Scripts available in a@1.0.0 via `npm run-script`:'], - [' glorp\n echo a doing the glerp glop'], - [''], + 'Scripts available in a@1.0.0 via `npm run-script`:', + ' glorp\n echo a doing the glerp glop', + '', ]) }) t.test('list regular scripts, filtered by parent folder', async t => { const { outputs } = await mockWorkspaces(t, { workspaces: ['./packages'] }) t.strictSame(outputs, [ - ['Scripts available in a@1.0.0 via `npm run-script`:'], - [' glorp\n echo a doing the glerp glop'], - [''], - ['Scripts available in b@2.0.0 via `npm run-script`:'], - [' glorp\n echo b doing the glerp glop'], - [''], - ['Lifecycle scripts included in c@1.0.0:'], - [' test\n exit 0'], - [' posttest\n echo posttest'], - ['\navailable via `npm run-script`:'], - [' lorem\n echo c lorem'], - [''], - ['Lifecycle scripts included in d@1.0.0:'], - [' test\n exit 0'], - [' posttest\n echo posttest'], - [''], - ['Lifecycle scripts included in e:'], - [' test\n exit 0'], - [' start\n echo start something'], - [''], + 'Scripts available in a@1.0.0 via `npm run-script`:', + ' glorp\n echo a doing the glerp glop', + '', + 'Scripts available in b@2.0.0 via `npm run-script`:', + ' glorp\n echo b doing the glerp glop', + '', + 'Lifecycle scripts included in c@1.0.0:', + ' test\n exit 0', + ' posttest\n echo posttest', + '\navailable via `npm run-script`:', + ' lorem\n echo c lorem', + '', + 'Lifecycle scripts included in d@1.0.0:', + ' test\n exit 0', + ' posttest\n echo posttest', + '', + 'Lifecycle scripts included in e:', + ' test\n exit 0', + ' start\n echo start something', + '', ]) }) t.test('list all scripts with colors', async t => { const { outputs } = await mockWorkspaces(t, { color: 'always' }) t.strictSame(outputs, [ - [ - /* eslint-disable-next-line max-len */ - '\u001b[1mScripts\u001b[22m available in \x1B[32ma@1.0.0\x1B[39m via `\x1B[34mnpm run-script\x1B[39m`:', - ], - [' glorp\n \x1B[2mecho a doing the glerp glop\x1B[22m'], - [''], - [ - /* eslint-disable-next-line max-len */ - '\u001b[1mScripts\u001b[22m available in \x1B[32mb@2.0.0\x1B[39m via `\x1B[34mnpm run-script\x1B[39m`:', - ], - [' glorp\n \x1B[2mecho b doing the glerp glop\x1B[22m'], - [''], - ['\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32mc@1.0.0\x1B[39m:'], - [' test\n \x1B[2mexit 0\x1B[22m'], - [' posttest\n \x1B[2mecho posttest\x1B[22m'], - ['\navailable via `\x1B[34mnpm run-script\x1B[39m`:'], - [' lorem\n \x1B[2mecho c lorem\x1B[22m'], - [''], - ['\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32md@1.0.0\x1B[39m:'], - [' test\n \x1B[2mexit 0\x1B[22m'], - [' posttest\n \x1B[2mecho posttest\x1B[22m'], - [''], - ['\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32me\x1B[39m:'], - [' test\n \x1B[2mexit 0\x1B[22m'], - [' start\n \x1B[2mecho start something\x1B[22m'], - [''], + /* eslint-disable-next-line max-len */ + '\u001b[1mScripts\u001b[22m available in \x1B[32ma@1.0.0\x1B[39m via `\x1B[34mnpm run-script\x1B[39m`:', + ' glorp\n \x1B[2mecho a doing the glerp glop\x1B[22m', + '', + /* eslint-disable-next-line max-len */ + '\u001b[1mScripts\u001b[22m available in \x1B[32mb@2.0.0\x1B[39m via `\x1B[34mnpm run-script\x1B[39m`:', + ' glorp\n \x1B[2mecho b doing the glerp glop\x1B[22m', + '', + '\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32mc@1.0.0\x1B[39m:', + ' test\n \x1B[2mexit 0\x1B[22m', + ' posttest\n \x1B[2mecho posttest\x1B[22m', + '\navailable via `\x1B[34mnpm run-script\x1B[39m`:', + ' lorem\n \x1B[2mecho c lorem\x1B[22m', + '', + '\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32md@1.0.0\x1B[39m:', + ' test\n \x1B[2mexit 0\x1B[22m', + ' posttest\n \x1B[2mecho posttest\x1B[22m', + '', + '\x1B[0m\x1B[1mLifecycle scripts\x1B[22m\x1B[0m included in \x1B[32me\x1B[39m:', + ' test\n \x1B[2mexit 0\x1B[22m', + ' start\n \x1B[2mecho start something\x1B[22m', + '', ]) }) t.test('list all scripts --json', async t => { const { outputs } = await mockWorkspaces(t, { json: true }) t.strictSame(outputs, [ - [ - '{\n' + + + '{\n' + ' "a": {\n' + ' "glorp": "echo a doing the glerp glop"\n' + ' },\n' + @@ -722,22 +716,22 @@ t.test('workspaces', async t => { ' },\n' + ' "noscripts": {}\n' + '}', - ], + ]) }) t.test('list all scripts --parseable', async t => { const { outputs } = await mockWorkspaces(t, { parseable: true }) t.strictSame(outputs, [ - ['a:glorp:echo a doing the glerp glop'], - ['b:glorp:echo b doing the glerp glop'], - ['c:test:exit 0'], - ['c:posttest:echo posttest'], - ['c:lorem:echo c lorem'], - ['d:test:exit 0'], - ['d:posttest:echo posttest'], - ['e:test:exit 0'], - ['e:start:echo start something'], + 'a:glorp:echo a doing the glerp glop', + 'b:glorp:echo b doing the glerp glop', + 'c:test:exit 0', + 'c:posttest:echo posttest', + 'c:lorem:echo c lorem', + 'd:test:exit 0', + 'd:posttest:echo posttest', + 'e:test:exit 0', + 'e:start:echo start something', ]) }) diff --git a/deps/npm/test/lib/commands/search.js b/deps/npm/test/lib/commands/search.js index 596c8499092291..de4a58ca78a8f5 100644 --- a/deps/npm/test/lib/commands/search.js +++ b/deps/npm/test/lib/commands/search.js @@ -4,206 +4,277 @@ const MockRegistry = require('@npmcli/mock-registry') const libnpmsearchResultFixture = require('../../fixtures/libnpmsearch-stream-result.js') -t.test('no args', async t => { - const { npm } = await loadMockNpm(t) - await t.rejects( - npm.exec('search', []), - /search must be called with arguments/, - 'should throw usage instructions' - ) -}) - -t.test('search text', async t => { - const { npm, joinedOutput } = await loadMockNpm(t) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), +t.test('search', t => { + t.test('no args', async t => { + const { npm } = await loadMockNpm(t) + await t.rejects( + npm.exec('search', []), + /search must be called with arguments/, + 'should throw usage instructions' + ) }) - registry.search({ results: libnpmsearchResultFixture }) - await npm.exec('search', ['libnpm']) - t.matchSnapshot(joinedOutput(), 'should have expected search results') -}) + t.test(' text', async t => { + const { npm, joinedOutput } = await loadMockNpm(t) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) -t.test('search --json', async t => { - const { npm, joinedOutput } = await loadMockNpm(t, { config: { json: 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') }) - registry.search({ results: libnpmsearchResultFixture }) + t.test(' --json', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { json: true } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) - await npm.exec('search', ['libnpm']) + registry.search({ results: libnpmsearchResultFixture }) - t.same( - JSON.parse(joinedOutput()), - libnpmsearchResultFixture, - 'should have expected search results as json' - ) -}) + await npm.exec('search', ['libnpm']) -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'), + t.same( + JSON.parse(joinedOutput()), + libnpmsearchResultFixture, + 'should have expected search results as json' + ) }) - registry.search({ results: libnpmsearchResultFixture }) - await npm.exec('search', ['libnpm']) - t.matchSnapshot(joinedOutput(), 'should have expected search results as parseable') -}) + t.test(' --parseable', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { parseable: true } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) -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'), + registry.search({ results: libnpmsearchResultFixture }) + await npm.exec('search', ['libnpm']) + t.matchSnapshot(joinedOutput(), 'should have expected search results as parseable') }) - registry.search({ results: libnpmsearchResultFixture }) - await npm.exec('search', ['libnpm']) - t.matchSnapshot(joinedOutput(), 'should have expected search results with color') -}) + t.test(' --color', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { color: 'always' } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) -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'), + registry.search({ results: libnpmsearchResultFixture }) + await npm.exec('search', ['libnpm']) + t.matchSnapshot(joinedOutput(), 'should have expected search results with color') }) - registry.search({ results: libnpmsearchResultFixture }) - await npm.exec('search', ['/libnpm/']) - t.matchSnapshot(joinedOutput(), 'should have expected search results with color') -}) + t.test('//--color', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { color: 'always' } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) -t.test('search ', async t => { - const { npm, joinedOutput } = await loadMockNpm(t) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), - }) - - registry.search({ results: [{ - name: 'foo', - scope: 'unscoped', - version: '1.0.0', - description: '', - keywords: [], - date: null, - author: { name: 'Foo', email: 'foo@npmjs.com' }, - publisher: { name: 'Foo', email: 'foo@npmjs.com' }, - maintainers: [ - { username: 'foo', email: 'foo@npmjs.com' }, - ], - }, { - name: 'libnpmversion', - scope: 'unscoped', - version: '1.0.0', - description: '', - keywords: [], - date: null, - author: { name: 'Foo', email: 'foo@npmjs.com' }, - publisher: { name: 'Foo', email: 'foo@npmjs.com' }, - maintainers: [ - { username: 'foo', email: 'foo@npmjs.com' }, - ], - }] }) - - await npm.exec('search', ['foo']) - - t.matchSnapshot(joinedOutput(), 'should have filtered expected search results') -}) + registry.search({ results: libnpmsearchResultFixture }) + await npm.exec('search', ['/libnpm/']) + t.matchSnapshot(joinedOutput(), 'should have expected search results with color') + }) -t.test('empty search results', async t => { - const { npm, joinedOutput } = await loadMockNpm(t) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), + t.test('', async t => { + const { npm, joinedOutput } = await loadMockNpm(t) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + + registry.search({ results: [{ + name: 'foo', + scope: 'unscoped', + version: '1.0.0', + description: '', + keywords: [], + date: null, + author: { name: 'Foo', email: 'foo@npmjs.com' }, + publisher: { username: 'foo', email: 'foo@npmjs.com' }, + maintainers: [ + { username: 'foo', email: 'foo@npmjs.com' }, + ], + }, { + name: 'custom-registry', + scope: 'unscoped', + version: '1.0.0', + description: '', + keywords: [], + date: null, + author: { name: 'Foo', email: 'foo@npmjs.com' }, + maintainers: [ + { username: 'foo', email: 'foo@npmjs.com' }, + ], + }, { + name: 'libnpmversion', + scope: 'unscoped', + version: '1.0.0', + description: '', + keywords: [], + date: null, + author: { name: 'Foo', email: 'foo@npmjs.com' }, + publisher: { username: 'foo', email: 'foo@npmjs.com' }, + maintainers: [ + { username: 'foo', email: 'foo@npmjs.com' }, + ], + }] }) + + await npm.exec('search', ['foo']) + + t.matchSnapshot(joinedOutput(), 'should have filtered expected search results') }) - registry.search({ results: [] }) - await npm.exec('search', ['foo']) + t.test('no publisher', async t => { + const { npm, joinedOutput } = await loadMockNpm(t) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + + registry.search({ results: [{ + name: 'custom-registry', + scope: 'unscoped', + version: '1.0.0', + description: '', + keywords: [], + date: null, + author: { name: 'Foo', email: 'foo@npmjs.com' }, + maintainers: [ + { username: 'foo', email: 'foo@npmjs.com' }, + ], + }, { + name: 'libnpmversion', + scope: 'unscoped', + version: '1.0.0', + description: '', + keywords: [], + date: null, + author: { name: 'Foo', email: 'foo@npmjs.com' }, + publisher: { username: 'foo', email: 'foo@npmjs.com' }, + maintainers: [ + { username: 'foo', email: 'foo@npmjs.com' }, + ], + }] }) + + await npm.exec('search', ['custom']) + + t.matchSnapshot(joinedOutput(), 'should have filtered expected search results') + }) - t.matchSnapshot(joinedOutput(), 'should have expected search results') -}) + t.test('empty search results', async t => { + const { npm, joinedOutput } = await loadMockNpm(t) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) -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'), - }) + registry.search({ results: [] }) + await npm.exec('search', ['foo']) - registry.search({ results: [] }) + t.matchSnapshot(joinedOutput(), 'should have expected search results') + }) - await npm.exec('search', ['foo']) - t.equal(joinedOutput(), '\n[]\n', 'should have expected empty square brackets') -}) + 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'), + }) -t.test('search api response error', async t => { - const { npm } = await loadMockNpm(t) + registry.search({ results: [] }) - const registry = new MockRegistry({ - tap: t, - registry: npm.config.get('registry'), + await npm.exec('search', ['foo']) + t.equal(joinedOutput(), '\n[]', 'should have expected empty square brackets') }) - registry.search({ error: 'ERR' }) + t.test('api response error', async t => { + const { npm } = await loadMockNpm(t) - await t.rejects( - npm.exec('search', ['foo']), - /ERR/, - 'should throw response error' - ) -}) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) -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({ error: 'ERR' }) - registry.search({ results: libnpmsearchResultFixture }) - await npm.exec('search', ['libnpm']) - t.matchSnapshot(joinedOutput(), 'results should not have libnpmversion') -}) + await t.rejects( + npm.exec('search', ['foo']), + /ERR/, + 'should throw response error' + ) + }) -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'), + t.test('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('exclude string json', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + json: true, + searchexclude: 'libnpmversion', + }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) + + registry.search({ results: libnpmsearchResultFixture }) + await npm.exec('search', ['libnpm']) + t.matchSnapshot(JSON.parse(joinedOutput()), 'results should not have libnpmversion') }) - registry.search({ results: libnpmsearchResultFixture }) - await npm.exec('search', ['libnpm']) - t.matchSnapshot(joinedOutput(), 'results should not have nlf') -}) + t.test('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'), + }) -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 nlf') }) - registry.search({ results: libnpmsearchResultFixture }) - await npm.exec('search', ['libnpm']) - t.matchSnapshot(joinedOutput(), 'results should not have libnpmversion') -}) + t.test('exclude regex', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { config: { searchexclude: '/version/' } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + }) -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') }) - registry.search({ results: libnpmsearchResultFixture }) - await npm.exec('search', ['libnpm']) - t.matchSnapshot(joinedOutput(), 'results should not have libnpmversion') + t.test('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') + }) + t.end() }) diff --git a/deps/npm/test/lib/commands/shrinkwrap.js b/deps/npm/test/lib/commands/shrinkwrap.js index 604a7db7a0b353..c5909a3ceaeac2 100644 --- a/deps/npm/test/lib/commands/shrinkwrap.js +++ b/deps/npm/test/lib/commands/shrinkwrap.js @@ -24,9 +24,8 @@ t.formatSnapshot = obj => // Run shrinkwrap against a specified prefixDir with config items // and make some assertions that should always be true. Sets // the results on t.context for use in child tests -const shrinkwrap = async (t, prefixDir = {}, config = {}, mocks = {}) => { +const shrinkwrap = async (t, prefixDir = {}, config = {}) => { const { npm, logs } = await loadMockNpm(t, { - mocks, config, prefixDir, }) @@ -37,13 +36,13 @@ const shrinkwrap = async (t, prefixDir = {}, config = {}, mocks = {}) => { const oldFile = resolve(npm.prefix, 'package-lock.json') t.notOk(fs.existsSync(oldFile), 'package-lock is always deleted') - t.same(logs.warn, [], 'no warnings') t.teardown(() => delete t.context) t.context = { localPrefix: prefixDir, config, shrinkwrap: JSON.parse(fs.readFileSync(newFile)), - logs: logs.notice.map(([, m]) => m), + logs: logs.notice, + warn: logs.warn, } } @@ -107,6 +106,8 @@ const NOTICES = { ], UPDATED: (v = '') => [`npm-shrinkwrap.json updated to version ${v}`], SAME: () => [`npm-shrinkwrap.json up to date`], + CONVERTING: (current, next) => + [`Converting lock file (npm-shrinkwrap.json) from v${current} -> v${next}`], } t.test('with nothing', t => @@ -114,10 +115,12 @@ t.test('with nothing', t => ancient: { shrinkwrap: { lockfileVersion: 3 }, logs: NOTICES.CREATED(3), + warn: [], }, ancientUpgrade: { shrinkwrap: { lockfileVersion: 3 }, logs: NOTICES.CREATED(3), + warn: [], }, }) ) @@ -127,22 +130,27 @@ t.test('with package-lock.json', t => ancient: { shrinkwrap: { lockfileVersion: 3 }, logs: NOTICES.RENAMED(3), + warn: NOTICES.CONVERTING(1, 3), }, ancientUpgrade: { shrinkwrap: { lockfileVersion: 3 }, logs: NOTICES.RENAMED(3), + warn: NOTICES.CONVERTING(1, 3), }, existing: { shrinkwrap: { lockfileVersion: 2 }, logs: NOTICES.RENAMED(), + warn: [], }, existingUpgrade: { shrinkwrap: { lockfileVersion: 3 }, logs: NOTICES.RENAMED(3), + warn: NOTICES.CONVERTING(2, 3), }, existingDowngrade: { shrinkwrap: { lockfileVersion: 1 }, logs: NOTICES.RENAMED(1), + warn: NOTICES.CONVERTING(2, 1), }, }) ) @@ -152,22 +160,27 @@ t.test('with npm-shrinkwrap.json', t => ancient: { shrinkwrap: { lockfileVersion: 3 }, logs: NOTICES.UPDATED(3), + warn: NOTICES.CONVERTING(1, 3), }, ancientUpgrade: { shrinkwrap: { lockfileVersion: 3 }, logs: NOTICES.UPDATED(3), + warn: NOTICES.CONVERTING(1, 3), }, existing: { shrinkwrap: { lockfileVersion: 2 }, logs: NOTICES.SAME(), + warn: [], }, existingUpgrade: { shrinkwrap: { lockfileVersion: 3 }, logs: NOTICES.UPDATED(3), + warn: NOTICES.CONVERTING(2, 3), }, existingDowngrade: { shrinkwrap: { lockfileVersion: 1 }, logs: NOTICES.UPDATED(1), + warn: NOTICES.CONVERTING(2, 1), }, }) ) @@ -177,22 +190,27 @@ t.test('with hidden lockfile', t => ancient: { shrinkwrap: { lockfileVersion: 1 }, logs: NOTICES.CREATED(), + warn: [], }, ancientUpgrade: { shrinkwrap: { lockfileVersion: 3 }, logs: NOTICES.CREATED(), + warn: NOTICES.CONVERTING(1, 3), }, existing: { shrinkwrap: { lockfileVersion: 2 }, logs: NOTICES.CREATED(), + warn: [], }, existingUpgrade: { shrinkwrap: { lockfileVersion: 3 }, logs: NOTICES.CREATED(3), + warn: NOTICES.CONVERTING(2, 3), }, existingDowngrade: { shrinkwrap: { lockfileVersion: 1 }, logs: NOTICES.CREATED(1), + warn: NOTICES.CONVERTING(2, 1), }, }) ) diff --git a/deps/npm/test/lib/commands/stars.js b/deps/npm/test/lib/commands/stars.js index d92ced950291f5..fc38ca77ac7810 100644 --- a/deps/npm/test/lib/commands/stars.js +++ b/deps/npm/test/lib/commands/stars.js @@ -18,7 +18,7 @@ const mockStars = async (t, { npmFetch = noop, exec = true, ...opts }) => { return { ...mock, result: mock.stars.output, - logs: () => mock.logs.filter(l => l[1] === 'stars').map(l => l[2]), + logs: () => mock.logs.byTitle('stars'), } } @@ -87,7 +87,7 @@ t.test('unauthorized request', async t => { t.strictSame( logs(), - ['auth is required to look up your username'], + ['stars auth is required to look up your username'], 'should warn auth required msg' ) @@ -121,7 +121,7 @@ t.test('no pkg starred', async t => { t.strictSame( logs(), - ['user has not starred any packages'], + ['stars user has not starred any packages'], 'should warn no starred packages msg' ) }) diff --git a/deps/npm/test/lib/commands/token.js b/deps/npm/test/lib/commands/token.js index 2bc4af4a81a3d1..f60a938b5b34b3 100644 --- a/deps/npm/test/lib/commands/token.js +++ b/deps/npm/test/lib/commands/token.js @@ -1,33 +1,38 @@ const t = require('tap') -const mockNpm = require('../../fixtures/mock-npm') +const { load: loadMockNpm } = require('../../fixtures/mock-npm.js') +const MockRegistry = require('@npmcli/mock-registry') +const mockGlobals = require('@npmcli/mock-globals') +const stream = require('node:stream') -const mockToken = async (t, { profile, getCredentialsByURI, readUserInfo, ...opts } = {}) => { - const mocks = {} +const authToken = 'abcd1234' +const password = 'this is not really a password' - if (profile) { - mocks['npm-profile'] = profile - } - - if (readUserInfo) { - mocks['{LIB}/utils/read-user-info.js'] = readUserInfo - } - - const mock = await mockNpm(t, { - ...opts, - command: 'token', - mocks, - }) - - // XXX: replace with mock registry - if (getCredentialsByURI) { - mock.npm.config.getCredentialsByURI = getCredentialsByURI - } - - return mock +const auth = { + '//registry.npmjs.org/:_authToken': authToken, } +const now = new Date().toISOString() +const tokens = [ + { + key: 'abcd1234abcd1234', + token: 'efgh5678efgh5678', + cidr_whitelist: null, + readonly: false, + created: now, + updated: now, + }, + { + key: 'abcd1256', + token: 'hgfe8765', + cidr_whitelist: ['192.168.1.1/32'], + readonly: true, + created: now, + updated: now, + }, +] + t.test('completion', async t => { - const { token } = await mockToken(t) + const { token } = await loadMockNpm(t, { command: 'token' }) const testComp = (argv, expect) => { t.resolveMatch(token.completion({ conf: { argv: { remain: argv } } }), expect, argv.join(' ')) @@ -44,476 +49,334 @@ t.test('completion', async t => { }) t.test('token foobar', async t => { - const { token } = await mockToken(t) + const { npm } = await loadMockNpm(t) - await t.rejects(token.exec(['foobar']), /foobar is not a recognized subcommand/) + await t.rejects(npm.exec('token', ['foobar']), /foobar is not a recognized subcommand/) }) t.test('token list', async t => { - const now = new Date().toISOString() - const tokens = [ - { - key: 'abcd1234abcd1234', - token: 'efgh5678efgh5678', - cidr_whitelist: null, - readonly: false, - created: now, - updated: now, - }, - { - key: 'abcd1256', - token: 'hgfe8765', - cidr_whitelist: ['192.168.1.1/32'], - readonly: true, - created: now, - updated: now, - }, - ] - - const { token, joinedOutput } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org', otp: '123456' }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { token: 'thisisnotarealtoken' } - }, - profile: { - listTokens: conf => { - t.same(conf.auth, { token: 'thisisnotarealtoken', otp: '123456' }) - return tokens - }, - }, + const { npm, outputs } = await loadMockNpm(t, { + config: { ...auth }, }) - - await token.exec([]) - - const lines = joinedOutput().split(/\r?\n/) - t.match(lines[3], ' abcd123 ', 'includes the trimmed key') - t.match(lines[3], ' efgh56… ', 'includes the trimmed token') - t.match(lines[3], ` ${now.slice(0, 10)} `, 'includes the trimmed creation timestamp') - t.match(lines[3], ' no ', 'includes the "no" string for readonly state') - t.match(lines[5], ' abcd125 ', 'includes the trimmed key') - t.match(lines[5], ' hgfe87… ', 'includes the trimmed token') - t.match(lines[5], ` ${now.slice(0, 10)} `, 'includes the trimmed creation timestamp') - t.match(lines[5], ' yes ', 'includes the "no" string for readonly state') - t.match(lines[5], ` ${tokens[1].cidr_whitelist.join(',')} `, 'includes the cidr whitelist') + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, + }) + registry.getTokens(tokens) + await npm.exec('token', []) + t.strictSame(outputs, [ + `Publish token efgh5678efgh5678… with id abcd123 created ${now.slice(0, 10)}`, + '', + `Read only token hgfe8765… with id abcd125 created ${now.slice(0, 10)}`, + 'with IP whitelist: 192.168.1.1/32', + '', + ]) }) t.test('token list json output', async t => { - const now = new Date().toISOString() - const tokens = [ - { - key: 'abcd1234abcd1234', - token: 'efgh5678efgh5678', - cidr_whitelist: null, - readonly: false, - created: now, - updated: now, - }, - ] - - const { token, joinedOutput } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org', json: true }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { username: 'foo', password: 'bar' } - }, - profile: { - listTokens: conf => { - t.same( - conf.auth, - { basic: { username: 'foo', password: 'bar' } }, - 'passes the correct auth' - ) - return tokens - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, + json: true, }, - }) - - await token.exec(['list']) - + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, + }) + registry.getTokens(tokens) + await npm.exec('token', ['list']) const parsed = JSON.parse(joinedOutput()) t.match(parsed, tokens, 'prints the json parsed tokens') }) t.test('token list parseable output', async t => { - const now = new Date().toISOString() - const tokens = [ - { - key: 'abcd1234abcd1234', - token: 'efgh5678efgh5678', - cidr_whitelist: null, - readonly: false, - created: now, - updated: now, - }, - { - key: 'efgh5678ijkl9101', - token: 'hgfe8765', - cidr_whitelist: ['192.168.1.1/32'], - readonly: true, - created: now, - updated: now, - }, - ] - - const { token, joinedOutput } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org', parseable: true }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { auth: Buffer.from('foo:bar').toString('base64') } - }, - profile: { - listTokens: conf => { - t.same( - conf.auth, - { basic: { username: 'foo', password: 'bar' } }, - 'passes the correct auth' - ) - return tokens - }, + const { npm, outputs } = await loadMockNpm(t, { + config: { + ...auth, + parseable: true, }, }) - - await token.exec(['list']) - - const lines = joinedOutput().split(/\r?\n/) - - t.equal( - lines[0], - ['key', 'token', 'created', 'readonly', 'CIDR whitelist'].join('\t'), - 'prints header' - ) - - t.equal( - lines[1], - [tokens[0].key, tokens[0].token, tokens[0].created, tokens[0].readonly, ''].join('\t'), - 'prints token info' - ) - - t.equal( - lines[2], - [ - tokens[1].key, - tokens[1].token, - tokens[1].created, - tokens[1].readonly, - tokens[1].cidr_whitelist.join(','), - ].join('\t'), - 'prints token info' - ) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, + }) + registry.getTokens(tokens) + await npm.exec('token', []) + t.strictSame(outputs, [ + 'key\ttoken\tcreated\treadonly\tCIDR whitelist', + `abcd1234abcd1234\tefgh5678efgh5678\t${now}\tfalse\t`, + `abcd1256\thgfe8765\t${now}\ttrue\t192.168.1.1/32`, + ]) }) t.test('token revoke', async t => { - const { token, joinedOutput } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org' }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return {} - }, - profile: { - listTokens: conf => { - t.same(conf.auth, {}, 'passes the correct empty auth') - return Promise.resolve([{ key: 'abcd1234' }]) - }, - removeToken: key => { - t.equal(key, 'abcd1234', 'deletes the correct token') - }, - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { ...auth }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, }) - await token.exec(['rm', 'abcd']) + registry.getTokens(tokens) + registry.nock.delete(`/-/npm/v1/tokens/token/${tokens[0].key}`).reply(200) + await npm.exec('token', ['rm', tokens[0].key.slice(0, 8)]) t.equal(joinedOutput(), 'Removed 1 token') }) t.test('token revoke multiple tokens', async t => { - const { token, joinedOutput } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org' }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { token: 'thisisnotarealtoken' } - }, - profile: { - listTokens: () => Promise.resolve([{ key: 'abcd1234' }, { key: 'efgh5678' }]), - removeToken: key => { - // this will run twice - t.ok(['abcd1234', 'efgh5678'].includes(key), 'deletes the correct token') - }, - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { ...auth }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, }) - await token.exec(['revoke', 'abcd', 'efgh']) + registry.getTokens(tokens) + registry.nock.delete(`/-/npm/v1/tokens/token/${tokens[0].key}`).reply(200) + registry.nock.delete(`/-/npm/v1/tokens/token/${tokens[1].key}`).reply(200) + await npm.exec('token', ['rm', tokens[0].key.slice(0, 8), tokens[1].key.slice(0, 8)]) t.equal(joinedOutput(), 'Removed 2 tokens') }) t.test('token revoke json output', async t => { - const { token, joinedOutput } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org', json: true }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { token: 'thisisnotarealtoken' } - }, - profile: { - listTokens: () => Promise.resolve([{ key: 'abcd1234' }]), - removeToken: key => { - t.equal(key, 'abcd1234', 'deletes the correct token') - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, + json: true, }, - + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, }) - await token.exec(['delete', 'abcd']) + registry.getTokens(tokens) + registry.nock.delete(`/-/npm/v1/tokens/token/${tokens[0].key}`).reply(200) + await npm.exec('token', ['rm', tokens[0].key.slice(0, 8)]) const parsed = JSON.parse(joinedOutput()) - t.same(parsed, ['abcd1234'], 'logs the token as json') + t.same(parsed, [tokens[0].key], 'logs the token as json') }) t.test('token revoke parseable output', async t => { - const { token, joinedOutput } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org', parseable: true }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { token: 'thisisnotarealtoken' } - }, - profile: { - listTokens: () => Promise.resolve([{ key: 'abcd1234' }]), - removeToken: key => { - t.equal(key, 'abcd1234', 'deletes the correct token') - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, + parseable: true, }, }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, + }) - await token.exec(['remove', 'abcd']) - - t.equal(joinedOutput(), 'abcd1234', 'logs the token as a string') + registry.getTokens(tokens) + registry.nock.delete(`/-/npm/v1/tokens/token/${tokens[0].key}`).reply(200) + await npm.exec('token', ['rm', tokens[0].key.slice(0, 8)]) + t.equal(joinedOutput(), tokens[0].key, 'logs the token as a string') }) t.test('token revoke by token', async t => { - const { token, joinedOutput } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org' }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { token: 'thisisnotarealtoken' } - }, - profile: { - listTokens: () => Promise.resolve([{ key: 'abcd1234', token: 'efgh5678' }]), - removeToken: key => { - t.equal(key, 'efgh5678', 'passes through user input') - }, - }, + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { ...auth }, }) - - await token.exec(['rm', 'efgh5678']) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, + }) + registry.getTokens(tokens) + registry.nock.delete(`/-/npm/v1/tokens/token/${tokens[0].token}`).reply(200) + await npm.exec('token', ['rm', tokens[0].token]) t.equal(joinedOutput(), 'Removed 1 token') }) t.test('token revoke requires an id', async t => { - const { token } = await mockToken(t) + const { npm } = await loadMockNpm(t) - await t.rejects(token.exec(['rm']), /`` argument is required/) + await t.rejects(npm.exec('token', ['rm']), { + code: 'EUSAGE', + message: '`` argument is required', + }) }) t.test('token revoke ambiguous id errors', async t => { - const { token } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org' }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { token: 'thisisnotarealtoken' } - }, - profile: { - listTokens: () => Promise.resolve([{ key: 'abcd1234' }, { key: 'abcd5678' }]), - }, + const { npm } = await loadMockNpm(t, { + config: { ...auth }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, + }) + registry.getTokens(tokens) + await t.rejects(npm.exec('token', ['rm', 'abcd']), { + message: /Token ID "abcd" was ambiguous/, }) - - await t.rejects(token.exec(['rm', 'abcd']), /Token ID "abcd" was ambiguous/) }) -t.test('token revoke unknown id errors', async t => { - const { token } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org' }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { token: 'thisisnotarealtoken' } - }, - profile: { - listTokens: () => Promise.resolve([{ key: 'abcd1234' }]), - }, +t.test('token revoke unknown token', async t => { + const { npm } = await loadMockNpm(t, { + config: { ...auth }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, }) - await t.rejects(token.exec(['rm', 'efgh']), /Unknown token id or value "efgh"./) + registry.getTokens(tokens) + await t.rejects(npm.exec('token', ['rm', '0xnotreal']), + 'Unknown token id or value 0xnotreal' + ) }) t.test('token create', async t => { - const now = new Date().toISOString() - const password = 'thisisnotreallyapassword' - - const { token, joinedOutput } = await mockToken(t, { + const cidr = ['10.0.0.0/8', '192.168.1.0/24'] + const { npm, outputs } = await loadMockNpm(t, { config: { - registry: 'https://registry.npmjs.org', - cidr: ['10.0.0.0/8', '192.168.1.0/24'], - }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { token: 'thisisnotarealtoken' } - }, - readUserInfo: { - password: () => Promise.resolve(password), + ...auth, + cidr, }, - profile: { - createToken: (pw, readonly, cidr) => { - t.equal(pw, password) - t.equal(readonly, false) - t.same(cidr, ['10.0.0.0/8', '192.168.1.0/24'], 'defaults to empty array') - return { - key: 'abcd1234', - token: 'efgh5678', - created: now, - updated: now, - readonly: false, - cidr_whitelist: [], - } - }, - }, - }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, + }) + const stdin = new stream.PassThrough() + stdin.write(`${password}\n`) + mockGlobals(t, { + 'process.stdin': stdin, + 'process.stdout': new stream.PassThrough(), // to quiet readline + }, { replace: true }) + registry.createToken({ password, cidr }) + await npm.exec('token', ['create']) + t.strictSame(outputs, [ + '', + 'Created publish token n3wt0k3n', + 'with IP whitelist: 10.0.0.0/8,192.168.1.0/24', + ]) +}) - await token.exec(['create']) - - const lines = joinedOutput().split(/\r?\n/) - t.match(lines[1], 'token') - t.match(lines[1], 'efgh5678', 'prints the whole token') - t.match(lines[3], 'created') - t.match(lines[3], now, 'prints the correct timestamp') - t.match(lines[5], 'readonly') - t.match(lines[5], 'false', 'prints the readonly flag') - t.match(lines[7], 'cidr_whitelist') +t.test('token create read only', async t => { + const { npm, outputs } = await loadMockNpm(t, { + config: { + ...auth, + 'read-only': true, + }, + }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, + }) + const stdin = new stream.PassThrough() + stdin.write(`${password}\n`) + mockGlobals(t, { + 'process.stdin': stdin, + 'process.stdout': new stream.PassThrough(), // to quiet readline + }, { replace: true }) + registry.createToken({ readonly: true, password }) + await npm.exec('token', ['create']) + t.strictSame(outputs, [ + '', + 'Created read only token n3wt0k3n', + ]) }) t.test('token create json output', async t => { - const now = new Date().toISOString() - const password = 'thisisnotreallyapassword' - - const { token } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org', json: true }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { token: 'thisisnotarealtoken' } - }, - readUserInfo: { - password: () => Promise.resolve(password), - }, - profile: { - createToken: (pw, readonly, cidr) => { - t.equal(pw, password) - t.equal(readonly, false) - t.same(cidr, [], 'defaults to empty array') - return { - key: 'abcd1234', - token: 'efgh5678', - created: now, - updated: now, - readonly: false, - cidr_whitelist: [], - } - }, - }, - output: spec => { - t.type(spec, 'string', 'outputs a string') - const parsed = JSON.parse(spec) - t.same( - parsed, - { token: 'efgh5678', created: now, readonly: false, cidr_whitelist: [] }, - 'outputs the correct object' - ) + const cidr = ['10.0.0.0/8', '192.168.1.0/24'] + const { npm, joinedOutput } = await loadMockNpm(t, { + config: { + ...auth, + json: true, + cidr, }, }) - - await token.exec(['create']) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, + }) + const stdin = new stream.PassThrough() + stdin.write(`${password}\n`) + mockGlobals(t, { + 'process.stdin': stdin, + 'process.stdout': new stream.PassThrough(), // to quiet readline + }, { replace: true }) + registry.createToken({ password, cidr }) + await npm.exec('token', ['create']) + const parsed = JSON.parse(joinedOutput()) + t.match( + parsed, + { token: 'n3wt0k3n', readonly: false, cidr_whitelist: cidr } + ) + t.ok(parsed.created, 'also returns created') }) t.test('token create parseable output', async t => { - const now = new Date().toISOString() - const password = 'thisisnotreallyapassword' - - const { token, joinedOutput } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org', parseable: true }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { token: 'thisisnotarealtoken' } - }, - readUserInfo: { - password: () => Promise.resolve(password), - }, - profile: { - createToken: (pw, readonly, cidr) => { - t.equal(pw, password) - t.equal(readonly, false) - t.same(cidr, [], 'defaults to empty array') - return { - key: 'abcd1234', - token: 'efgh5678', - created: now, - updated: now, - readonly: false, - cidr_whitelist: [], - } - }, + const cidr = ['10.0.0.0/8', '192.168.1.0/24'] + const { npm, outputs } = await loadMockNpm(t, { + config: { + ...auth, + parseable: true, + cidr, }, }) - - await token.exec(['create']) - - const spec = joinedOutput().split(/\r?\n/) - - t.match(spec[0], 'token\tefgh5678', 'prints the token') - t.match(spec[1], `created\t${now}`, 'prints the created timestamp') - t.match(spec[2], 'readonly\tfalse', 'prints the readonly flag') - t.match(spec[3], 'cidr_whitelist\t', 'prints the cidr whitelist') + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: authToken, + }) + const stdin = new stream.PassThrough() + stdin.write(`${password}\n`) + mockGlobals(t, { + 'process.stdin': stdin, + 'process.stdout': new stream.PassThrough(), // to quiet readline + }, { replace: true }) + registry.createToken({ password, cidr }) + await npm.exec('token', ['create']) + t.equal(outputs[1], 'token\tn3wt0k3n') + t.ok(outputs[2].startsWith('created\t')) + t.equal(outputs[3], 'readonly\tfalse') + t.equal(outputs[4], 'cidr_whitelist\t10.0.0.0/8,192.168.1.0/24') }) t.test('token create ipv6 cidr', async t => { - const password = 'thisisnotreallyapassword' - - const { token } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org', cidr: '::1/128' }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { token: 'thisisnotarealtoken' } - }, - readUserInfo: { - password: () => Promise.resolve(password), + const { npm } = await loadMockNpm(t, { + config: { + ...auth, + cidr: '::1/128', }, }) - - await t.rejects( - token.exec(['create']), - { - code: 'EINVALIDCIDR', - message: /CIDR whitelist can only contain IPv4 addresses, ::1\/128 is IPv6/, - }, - 'returns correct error' - ) + await t.rejects(npm.exec('token', ['create'], { + code: 'EINVALIDCIDR', + message: /CIDR whitelist can only contain IPv4 addresses, ::1\/128 is IPv6/, + })) }) t.test('token create invalid cidr', async t => { - const password = 'thisisnotreallyapassword' - - const { token } = await mockToken(t, { - config: { registry: 'https://registry.npmjs.org', cidr: 'apple/cider' }, - getCredentialsByURI: uri => { - t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry') - return { token: 'thisisnotarealtoken' } - }, - readUserInfo: { - password: () => Promise.resolve(password), + const { npm } = await loadMockNpm(t, { + config: { + ...auth, + cidr: 'apple/cider', }, }) - - await t.rejects( - token.exec(['create']), - { code: 'EINVALIDCIDR', message: /CIDR whitelist contains invalid CIDR entry: apple\/cider/ }, - 'returns correct error' - ) + await t.rejects(npm.exec('token', ['create'], { + code: 'EINVALIDCIDR', + message: 'CIDR whitelist contains invalid CIDR entry: apple/cider', + })) }) diff --git a/deps/npm/test/lib/commands/update.js b/deps/npm/test/lib/commands/update.js index f42fb8a4146b02..e84e2c3142141b 100644 --- a/deps/npm/test/lib/commands/update.js +++ b/deps/npm/test/lib/commands/update.js @@ -64,10 +64,8 @@ t.test('update --depth=', async t => { config: { depth: 1 }, }) - const [title, msg] = logs.warn[0] - t.equal(title, 'update', 'should print expected title') t.match( - msg, + logs.warn.byTitle('update')[0], /The --depth option no longer has any effect/, 'should print expected warning message' ) diff --git a/deps/npm/test/lib/commands/version.js b/deps/npm/test/lib/commands/version.js index 8aa6c088bfc9b5..1f02f368f67bc0 100644 --- a/deps/npm/test/lib/commands/version.js +++ b/deps/npm/test/lib/commands/version.js @@ -36,11 +36,7 @@ t.test('node@1', async t => { t.strictSame( result(), - [{ - 'test-version-no-args': '3.2.1', - node: '1.0.0', - npm: '1.0.0', - }], + "{ 'test-version-no-args': '3.2.1', npm: '1.0.0', node: '1.0.0' }", 'should output expected values for various versions in npm' ) }) @@ -75,10 +71,7 @@ t.test('node@1', async t => { t.strictSame( result(), - [{ - npm: '1.0.0', - node: '1.0.0', - }], + `{ npm: '1.0.0', node: '1.0.0' }`, 'should not have package name on returning object' ) }) @@ -93,7 +86,7 @@ t.test('empty versions', async t => { }) await version.exec([]) - t.same(result(), ['{\n "npm": "1.0.0"\n}'], 'should return json stringified result') + t.same(result(), '{\n "npm": "1.0.0"\n}', 'should return json stringified result') }) t.test('with one arg', async t => { @@ -104,7 +97,7 @@ t.test('empty versions', async t => { }) await version.exec(['major']) - t.same(result(), ['v4.0.0'], 'outputs the new version prefixed by the tagVersionPrefix') + t.same(result(), 'v4.0.0', 'outputs the new version prefixed by the tagVersionPrefix') }) t.test('workspaces', async t => { @@ -139,14 +132,12 @@ t.test('empty versions', async t => { await version.exec([]) t.same( result(), - [ - { - 'workspaces-test': '1.0.0', - 'workspace-a': '1.0.0', - 'workspace-b': '1.0.0', - npm: '1.0.0', - }, - ], + `{ + 'workspace-a': '1.0.0', + 'workspace-b': '1.0.0', + 'workspaces-test': '1.0.0', + npm: '1.0.0' +}`, 'outputs includes main package and workspace versions' ) }) @@ -184,13 +175,7 @@ t.test('empty versions', async t => { await version.exec([]) t.same( result(), - [ - { - 'workspaces-test': '1.0.0', - 'workspace-a': '1.0.0', - npm: '1.0.0', - }, - ], + "{ 'workspace-a': '1.0.0', 'workspaces-test': '1.0.0', npm: '1.0.0' }", 'outputs includes main package and requested workspace versions' ) }) @@ -230,13 +215,7 @@ t.test('empty versions', async t => { await version.exec([]) t.same( result(), - [ - { - 'workspaces-test': '1.0.0', - 'workspace-a': '1.0.0', - npm: '1.0.0', - }, - ], + "{ 'workspace-a': '1.0.0', 'workspaces-test': '1.0.0', npm: '1.0.0' }", 'outputs includes main package and valid workspace versions' ) }) @@ -271,7 +250,7 @@ t.test('empty versions', async t => { await version.exec(['major']) t.same( - outputs.map(o => o[0]).slice(0, 4), + outputs.slice(0, 4), ['workspace-a', 'v2.0.0', 'workspace-b', 'v2.0.0'], 'outputs the new version for only the workspaces prefixed by the tagVersionPrefix' ) @@ -316,7 +295,7 @@ t.test('empty versions', async t => { await version.exec(['major']) t.same( - outputs.map(o => o[0]).slice(0, 4), + outputs.slice(0, 4), ['workspace-a', 'v2.0.0', 'workspace-b', 'v2.0.0'], 'outputs the new version for only the workspaces prefixed by the tagVersionPrefix' ) @@ -360,7 +339,7 @@ t.test('empty versions', async t => { }, }, mocks: { - libnpmversion: (arg, opts) => { + libnpmversion: () => { return '2.0.0' }, }, @@ -372,7 +351,7 @@ t.test('empty versions', async t => { await version.exec(['major']) t.same( - outputs.map(o => o[0]).slice(0, 4), + outputs.slice(0, 4), ['workspace-a', 'v2.0.0', 'workspace-b', 'v2.0.0'], 'outputs the new version for only the workspaces prefixed by the tagVersionPrefix' ) diff --git a/deps/npm/test/lib/commands/view.js b/deps/npm/test/lib/commands/view.js index 92c7fe47bda062..c50668791bbe59 100644 --- a/deps/npm/test/lib/commands/view.js +++ b/deps/npm/test/lib/commands/view.js @@ -48,9 +48,7 @@ const packument = (nv, opts) => { dist: { shasum: '123', tarball: 'http://hm.blue.com/1.0.0.tgz', - integrity: '---', fileCount: 1, - unpackedSize: 1, }, }, '1.0.1': { @@ -282,81 +280,81 @@ const loadMockNpm = async function (t, opts = {}) { } t.test('package from git', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { unicode: false } }) await view.exec(['https://github.com/npm/green']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('deprecated package with license, bugs, repository and other fields', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { unicode: false } }) await view.exec(['green@1.0.0']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('deprecated package with unicode', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { unicode: true } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { unicode: true } }) await view.exec(['green@1.0.0']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('package with more than 25 deps', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { unicode: false } }) await view.exec(['black@1.0.0']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('package with maintainers info as object', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { unicode: false } }) await view.exec(['pink@1.0.0']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('package with homepage', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { unicode: false } }) await view.exec(['orange@1.0.0']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('package with invalid version', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { unicode: false } }) await view.exec(['orange', 'versions']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('package with no versions', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { unicode: false } }) await view.exec(['brown']) - t.equal(outputs.join('\n'), '', 'no info to display') + t.equal(joinedOutput(), '', 'no info to display') }) t.test('package with no repo or homepage', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { unicode: false } }) await view.exec(['blue@1.0.0']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('package with semver range', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { unicode: false } }) await view.exec(['blue@^1.0.0']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('package with no modified time', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { unicode: false } }) await view.exec(['cyan@1.0.0']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('package with --json and semver range', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { json: true } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { json: true } }) await view.exec(['cyan@^1.0.0']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('package with --json and no versions', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { json: true } }) + const { view, joinedOutput } = await loadMockNpm(t, { config: { json: true } }) await view.exec(['brown']) - t.equal(outputs.join('\n'), '', 'no info to display') + t.equal(joinedOutput(), '', 'no info to display') }) t.test('package in cwd', async t => { @@ -368,76 +366,76 @@ t.test('package in cwd', async t => { } t.test('specific version', async t => { - const { view, outputs } = await loadMockNpm(t, { prefixDir }) + const { view, joinedOutput } = await loadMockNpm(t, { prefixDir }) await view.exec(['.@1.0.0']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('non-specific version', async t => { - const { view, outputs } = await loadMockNpm(t, { prefixDir }) + const { view, joinedOutput } = await loadMockNpm(t, { prefixDir }) await view.exec(['.']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('directory', async t => { - const { view, outputs } = await loadMockNpm(t, { prefixDir }) + const { view, joinedOutput } = await loadMockNpm(t, { prefixDir }) await view.exec(['./blue']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) }) t.test('specific field names', async t => { - const { view, outputs } = await loadMockNpm(t, { config: { color: false } }) - t.afterEach(() => outputs.length = 0) + const { view, joinedOutput, clearOutput } = await loadMockNpm(t, { config: { color: false } }) + t.afterEach(() => clearOutput()) t.test('readme', async t => { await view.exec(['yellow@1.0.0', 'readme']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('several fields', async t => { await view.exec(['yellow@1.0.0', 'name', 'version', 'foo[bar]']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('several fields with several versions', async t => { await view.exec(['yellow@1.x.x', 'author']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('nested field with brackets', async t => { await view.exec(['orange@1.0.0', 'dist[shasum]']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('maintainers with email', async t => { await view.exec(['yellow@1.0.0', 'maintainers', 'name']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('maintainers with url', async t => { await view.exec(['pink@1.0.0', 'maintainers']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('unknown nested field ', async t => { await view.exec(['yellow@1.0.0', 'dist.foobar']) - t.equal(outputs.join('\n'), '', 'no info to display') + t.equal(joinedOutput(), '', 'no info to display') }) t.test('array field - 1 element', async t => { await view.exec(['purple@1.0.0', 'maintainers.name']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('array field - 2 elements', async t => { await view.exec(['yellow@1.x.x', 'maintainers.name']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('fields with empty values', async t => { await view.exec(['yellow', 'empty']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) }) @@ -507,84 +505,84 @@ t.test('workspaces', async t => { } t.test('all workspaces', async t => { - const { view, outputs } = await loadMockNpm(t, { + const { view, joinedOutput } = await loadMockNpm(t, { prefixDir, config: { unicode: false, workspaces: true }, }) await view.exec([]) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('one specific workspace', async t => { - const { view, outputs } = await loadMockNpm(t, { + const { view, joinedOutput } = await loadMockNpm(t, { prefixDir, config: { unicode: false, workspace: ['green'] }, }) await view.exec([]) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('all workspaces --json', async t => { - const { view, outputs } = await loadMockNpm(t, { + const { view, joinedOutput } = await loadMockNpm(t, { prefixDir, config: { unicode: false, workspaces: true, json: true }, }) await view.exec([]) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('all workspaces single field', async t => { - const { view, outputs } = await loadMockNpm(t, { + const { view, joinedOutput } = await loadMockNpm(t, { prefixDir, config: { unicode: false, workspaces: true }, }) await view.exec(['.', 'name']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('all workspaces nonexistent field', async t => { - const { view, outputs } = await loadMockNpm(t, { + const { view, joinedOutput } = await loadMockNpm(t, { prefixDir, config: { unicode: false, workspaces: true }, }) await view.exec(['.', 'foo']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('all workspaces nonexistent field --json', async t => { - const { view, outputs } = await loadMockNpm(t, { + const { view, joinedOutput } = await loadMockNpm(t, { prefixDir, config: { unicode: false, workspaces: true, json: true }, }) await view.exec(['.', 'foo']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('all workspaces single field --json', async t => { - const { view, outputs } = await loadMockNpm(t, { + const { view, joinedOutput } = await loadMockNpm(t, { prefixDir, config: { unicode: false, workspaces: true, json: true }, }) await view.exec(['.', 'name']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('single workspace --json', async t => { - const { view, outputs } = await loadMockNpm(t, { + const { view, joinedOutput } = await loadMockNpm(t, { prefixDir, config: { unicode: false, workspace: ['green'], json: true }, }) await view.exec([]) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) }) t.test('remote package name', async t => { - const { view, logs, outputs } = await loadMockNpm(t, { + const { view, logs, joinedOutput } = await loadMockNpm(t, { prefixDir, config: { unicode: false, workspaces: true }, }) await view.exec(['pink']) - t.matchSnapshot(outputs.join('\n')) + t.matchSnapshot(joinedOutput()) t.matchSnapshot(logs.warn, 'should have warning of ignoring workspaces') }) }) diff --git a/deps/npm/test/lib/docs.js b/deps/npm/test/lib/docs.js index 7ace9b99957019..67afd1b54d91e6 100644 --- a/deps/npm/test/lib/docs.js +++ b/deps/npm/test/lib/docs.js @@ -22,7 +22,7 @@ t.test('shorthands', async t => { t.test('config', async t => { const keys = Object.keys(definitions) - const flat = Object.entries(definitions).filter(([_, d]) => d.flatten).map(([k]) => k) + const flat = Object.entries(definitions).filter(([, d]) => d.flatten).map(([k]) => k) const notFlat = keys.filter(k => !flat.includes(k)) t.matchSnapshot(keys, 'all keys') t.matchSnapshot(flat, 'keys that are flattened') @@ -74,7 +74,7 @@ t.test('basic usage', async t => { // are generated in the following test const { npm } = await loadMockNpm(t, { mocks: { - '{LIB}/utils/cmd-list.js': { commands: [] }, + '{LIB}/utils/cmd-list.js': { ...cmdList, commands: [] }, }, config: { userconfig: '/some/config/file/.npmrc' }, globals: { process: { platform: 'posix' } }, diff --git a/deps/npm/test/lib/load-all-commands.js b/deps/npm/test/lib/load-all-commands.js index d3846434489cee..c00da37eff3fc3 100644 --- a/deps/npm/test/lib/load-all-commands.js +++ b/deps/npm/test/lib/load-all-commands.js @@ -6,7 +6,7 @@ const t = require('tap') const util = require('util') const { load: loadMockNpm } = require('../fixtures/mock-npm.js') const { commands } = require('../../lib/utils/cmd-list.js') -const BaseCommand = require('../../lib/base-command.js') +const BaseCommand = require('../../lib/base-cmd.js') const isAsyncFn = (v) => typeof v === 'function' && /^\[AsyncFunction:/.test(util.inspect(v)) @@ -72,8 +72,8 @@ t.test('load each command', async t => { // usage t.match(impl.usage, cmd, 'usage contains the command') await npm.exec(cmd, []) - t.match(outputs[0][0], impl.usage, 'usage is what is output') - t.match(outputs[0][0], ctor.describeUsage, 'usage is what is output') + t.match(outputs[0], impl.usage, 'usage is what is output') + t.match(outputs[0], ctor.describeUsage, 'usage is what is output') t.notOk(impl.describeUsage, 'describe usage is only static') }) } diff --git a/deps/npm/test/lib/npm.js b/deps/npm/test/lib/npm.js index e9300ecfa6bd10..a965a79a3f528d 100644 --- a/deps/npm/test/lib/npm.js +++ b/deps/npm/test/lib/npm.js @@ -1,6 +1,7 @@ const t = require('tap') const { resolve, dirname, join } = require('path') const fs = require('fs') +const { time } = require('proc-log') const { load: loadMockNpm } = require('../fixtures/mock-npm.js') const mockGlobals = require('@npmcli/mock-globals') const { commands } = require('../../lib/utils/cmd-list.js') @@ -25,32 +26,20 @@ t.test('not yet loaded', async t => { t.test('npm.load', async t => { await t.test('load error', async t => { const { npm } = await loadMockNpm(t, { load: false }) - const loadError = new Error('load error') npm.config.load = async () => { - throw loadError + throw new Error('load error') } await t.rejects( () => npm.load(), /load error/ ) - - t.equal(npm.loadErr, loadError) - npm.config.load = async () => { - throw new Error('different error') - } - await t.rejects( - () => npm.load(), - /load error/, - 'loading again returns the original error' - ) - t.equal(npm.loadErr, loadError) }) await t.test('basic loading', async t => { - const { npm, logs, prefix: dir, cache, other } = await loadMockNpm(t, { + const { npm, logs, cache } = await loadMockNpm(t, { prefixDir: { node_modules: {} }, - otherDirs: { - newCache: {}, + config: { + timing: true, }, }) @@ -62,31 +51,18 @@ t.test('npm.load', async t => { t.match(npm, { flatOptions: {}, }) - t.match(logs.timing.filter(([p]) => p === 'npm:load'), [ - ['npm:load', /Completed in [0-9.]+ms/], + + t.match(logs.timing.filter((p) => /^npm:load/.test(p)), [ + /npm:load.* Completed in [0-9.]+ms/, ]) mockGlobals(t, { process: { platform: 'posix' } }) t.equal(resolve(npm.cache), resolve(cache), 'cache is cache') - npm.cache = other.newCache - t.equal(npm.config.get('cache'), other.newCache, 'cache setter sets config') - t.equal(npm.cache, other.newCache, 'cache getter gets new config') t.equal(npm.lockfileVersion, 2, 'lockfileVersion getter') t.equal(npm.prefix, npm.localPrefix, 'prefix is local prefix') t.not(npm.prefix, npm.globalPrefix, 'prefix is not global prefix') - npm.globalPrefix = npm.prefix - t.equal(npm.prefix, npm.globalPrefix, 'globalPrefix setter') - npm.localPrefix = dir + '/extra/prefix' - t.equal(npm.prefix, npm.localPrefix, 'prefix is local prefix after localPrefix setter') - t.not(npm.prefix, npm.globalPrefix, 'prefix is not global prefix after localPrefix setter') - - npm.prefix = dir + '/some/prefix' - t.equal(npm.prefix, npm.localPrefix, 'prefix is local prefix after prefix setter') - t.not(npm.prefix, npm.globalPrefix, 'prefix is not global prefix after prefix setter') - t.equal(npm.bin, npm.localBin, 'bin is local bin after prefix setter') - t.not(npm.bin, npm.globalBin, 'bin is not global bin after prefix setter') - t.equal(npm.dir, npm.localDir, 'dir is local dir after prefix setter') - t.not(npm.dir, npm.globalDir, 'dir is not global dir after prefix setter') + t.equal(npm.bin, npm.localBin, 'bin is local bin') + t.not(npm.bin, npm.globalBin, 'bin is not global bin') npm.config.set('global', true) t.equal(npm.prefix, npm.globalPrefix, 'prefix is global prefix after setting global') @@ -96,12 +72,6 @@ t.test('npm.load', async t => { t.equal(npm.dir, npm.globalDir, 'dir is global dir after setting global') t.not(npm.dir, npm.localDir, 'dir is not local dir after setting global') - npm.prefix = dir + '/new/global/prefix' - t.equal(npm.prefix, npm.globalPrefix, 'prefix is global prefix after prefix setter') - t.not(npm.prefix, npm.localPrefix, 'prefix is not local prefix after prefix setter') - t.equal(npm.bin, npm.globalBin, 'bin is global bin after prefix setter') - t.not(npm.bin, npm.localBin, 'bin is not local bin after prefix setter') - mockGlobals(t, { process: { platform: 'win32' } }) t.equal(npm.bin, npm.globalBin, 'bin is global bin in windows mode') t.equal(npm.dir, npm.globalDir, 'dir is global dir in windows mode') @@ -109,15 +79,12 @@ t.test('npm.load', async t => { await t.test('forceful loading', async t => { const { logs } = await loadMockNpm(t, { - globals: { - 'process.argv': [...process.argv, '--force', '--color', 'always'], + config: { + force: true, }, }) t.match(logs.warn, [ - [ - 'using --force', - 'Recommended protections disabled.', - ], + 'using --force Recommended protections disabled.', ]) }) @@ -127,33 +94,39 @@ t.test('npm.load', async t => { prefixDir: { bin: t.fixture('symlink', dirname(process.execPath)), }, + config: { + timing: true, + usage: '', + scope: 'foo', + }, + argv: [ + 'token', + 'revoke', + 'blergggg', + ], globals: (dirs) => ({ 'process.env.PATH': resolve(dirs.prefix, 'bin'), 'process.argv': [ node, process.argv[1], - '--usage', - '--scope=foo', - 'token', - 'revoke', - 'blergggg', ], }), }) t.equal(npm.config.get('scope'), '@foo', 'added the @ sign to scope') + t.match([ - ...logs.timing.filter(([p]) => p === 'npm:load:whichnode'), + ...logs.timing.filter((p) => p.startsWith('npm:load:whichnode')), ...logs.verbose, - ...logs.timing.filter(([p]) => p === 'npm:load'), + ...logs.timing.filter((p) => p.startsWith('npm:load')), ], [ - ['npm:load:whichnode', /Completed in [0-9.]+ms/], - ['node symlink', resolve(prefix, 'bin', node)], - ['title', 'npm token revoke blergggg'], - ['argv', '"--usage" "--scope" "foo" "token" "revoke" "blergggg"'], - ['logfile', /logs-max:\d+ dir:.*/], - ['logfile', /.*-debug-0.log/], - ['npm:load', /Completed in [0-9.]+ms/], + /npm:load:whichnode Completed in [0-9.]+ms/, + `node symlink ${resolve(prefix, 'bin', node)}`, + /title npm token revoke blergggg/, + /argv "token" "revoke" "blergggg".*"--usage" "--scope" "foo"/, + /logfile logs-max:\d+ dir:.*/, + /logfile .*-debug-0.log/, + /npm:load:.* Completed in [0-9.]+ms/, ]) t.equal(process.execPath, resolve(prefix, 'bin', node)) @@ -165,35 +138,21 @@ t.test('npm.load', async t => { t.equal(npm.flatOptions.npmCommand, 'll', 'npmCommand flatOption set') const ll = Npm.cmd('ll') - t.same(outputs, [[ll.describeUsage]], 'print usage') + t.same(outputs, [ll.describeUsage], 'print usage') npm.config.set('usage', false) outputs.length = 0 logs.length = 0 - await npm.exec('get', ['scope', '\u2010not-a-dash']) + await npm.exec('get', ['scope', 'usage']) t.strictSame([npm.command, npm.flatOptions.npmCommand], ['ll', 'll'], 'does not change npm.command when another command is called') t.match(logs, [ - [ - 'error', - 'arg', - 'Argument starts with non-ascii dash, this is probably invalid:', - '\u2010not-a-dash', - ], - [ - 'timing', - 'command:config', - /Completed in [0-9.]+ms/, - ], - [ - 'timing', - 'command:get', - /Completed in [0-9.]+ms/, - ], + /timing command:config Completed in [0-9.]+ms/, + /timing command:get Completed in [0-9.]+ms/, ]) - t.same(outputs, [['scope=@foo\n\u2010not-a-dash=undefined']]) + t.same(outputs, ['scope=@foo\nusage=false']) }) await t.test('--no-workspaces with --workspace', async t => { @@ -214,14 +173,9 @@ t.test('npm.load', async t => { workspaces: ['./packages/*'], }), }, - globals: { - 'process.argv': [ - process.execPath, - process.argv[1], - '--color', 'false', - '--workspaces', 'false', - '--workspace', 'a', - ], + config: { + workspaces: false, + workspace: 'a', }, }) await t.rejects( @@ -231,7 +185,7 @@ t.test('npm.load', async t => { }) await t.test('workspace-aware configs and commands', async t => { - const { npm, outputs } = await loadMockNpm(t, { + const { npm, joinedOutput } = await loadMockNpm(t, { prefixDir: { packages: { a: { @@ -255,13 +209,8 @@ t.test('npm.load', async t => { workspaces: ['./packages/*'], }), }, - globals: { - 'process.argv': [ - process.execPath, - process.argv[1], - '--color', 'false', - '--workspaces', 'true', - ], + config: { + workspaces: true, }, }) @@ -269,18 +218,7 @@ t.test('npm.load', async t => { t.equal(npm.command, 'run-script', 'npm.command set to canonical name') - t.match( - outputs, - [ - ['Lifecycle scripts included in a@1.0.0:'], - [' test\n echo test a'], - [''], - ['Lifecycle scripts included in b@1.0.0:'], - [' test\n echo test b'], - [''], - ], - 'should exec workspaces version of commands' - ) + t.matchSnapshot(joinedOutput(), 'should exec workspaces version of commands') }) await t.test('workspaces in global mode', async t => { @@ -308,16 +246,9 @@ t.test('npm.load', async t => { workspaces: ['./packages/*'], }), }, - globals: { - 'process.argv': [ - process.execPath, - process.argv[1], - '--color', - 'false', - '--workspaces', - '--global', - 'true', - ], + config: { + workspaces: true, + global: true, }, }) @@ -331,15 +262,11 @@ t.test('npm.load', async t => { t.test('set process.title', async t => { t.test('basic title setting', async t => { const { npm } = await loadMockNpm(t, { - globals: { - 'process.argv': [ - process.execPath, - process.argv[1], - '--usage', - '--scope=foo', - 'ls', - ], + config: { + usage: true, + scope: 'foo', }, + argv: ['ls'], }) t.equal(npm.title, 'npm ls') t.equal(process.title, 'npm ls') @@ -347,17 +274,11 @@ t.test('set process.title', async t => { t.test('do not expose token being revoked', async t => { const { npm } = await loadMockNpm(t, { - globals: { - 'process.argv': [ - process.execPath, - process.argv[1], - '--usage', - '--scope=foo', - 'token', - 'revoke', - `npm_${'a'.repeat(36)}`, - ], + config: { + usage: true, + scope: 'foo', }, + argv: ['token', 'revoke', `npm_${'a'.repeat(36)}`], }) t.equal(npm.title, 'npm token revoke npm_***') t.equal(process.title, 'npm token revoke npm_***') @@ -365,17 +286,11 @@ t.test('set process.title', async t => { t.test('do show *** unless a token is actually being revoked', async t => { const { npm } = await loadMockNpm(t, { - globals: { - 'process.argv': [ - process.execPath, - process.argv[1], - '--usage', - '--scope=foo', - 'token', - 'revoke', - 'notatoken', - ], + config: { + usage: true, + scope: 'foo', }, + argv: ['token', 'revoke', 'notatoken'], }) t.equal(npm.title, 'npm token revoke notatoken') t.equal(process.title, 'npm token revoke notatoken') @@ -442,42 +357,14 @@ t.test('cache dir', async t => { }) t.test('timings', async t => { - t.test('gets/sets timers', async t => { - const { npm, logs } = await loadMockNpm(t, { load: false }) - process.emit('time', 'foo') - process.emit('time', 'bar') - t.match(npm.unfinishedTimers.get('foo'), Number, 'foo timer is a number') - t.match(npm.unfinishedTimers.get('bar'), Number, 'foo timer is a number') - process.emit('timeEnd', 'foo') - process.emit('timeEnd', 'bar') - process.emit('timeEnd', 'baz') - // npm timer is started by default - process.emit('timeEnd', 'npm') - t.match(logs.timing, [ - ['foo', /Completed in [0-9]+ms/], - ['bar', /Completed in [0-9]+ms/], - ['npm', /Completed in [0-9]+ms/], - ]) - t.match(logs.silly, [[ - 'timing', - "Tried to end timer that doesn't exist:", - 'baz', - ]]) - t.notOk(npm.unfinishedTimers.has('foo'), 'foo timer is gone') - t.notOk(npm.unfinishedTimers.has('bar'), 'bar timer is gone') - t.match(npm.finishedTimers, { foo: Number, bar: Number, npm: Number }) - }) - t.test('writes timings file', async t => { - const { npm, cache, timingFile } = await loadMockNpm(t, { + const { npm, timingFile } = await loadMockNpm(t, { config: { timing: true }, }) - process.emit('time', 'foo') - process.emit('timeEnd', 'foo') - process.emit('time', 'bar') - npm.writeTimingFile() - t.match(npm.timingFile, cache) - t.match(npm.timingFile, /-timing.json$/) + time.start('foo') + time.end('foo') + time.start('bar') + npm.finish() const timings = await timingFile() t.match(timings, { metadata: { @@ -487,7 +374,6 @@ t.test('timings', async t => { }, unfinishedTimers: { bar: [Number, Number], - npm: [Number, Number], }, timers: { foo: Number, @@ -500,7 +386,7 @@ t.test('timings', async t => { const { npm, timingFile } = await loadMockNpm(t, { config: { timing: false }, }) - npm.writeTimingFile() + npm.finish() await t.rejects(() => timingFile()) }) @@ -513,44 +399,13 @@ t.test('timings', async t => { for (const [config, expectedDisplay, expectedTiming] of timingDisplay) { const msg = `${JSON.stringify(config)}, display:${expectedDisplay}, timing:${expectedTiming}` await t.test(`timing display: ${msg}`, async t => { - const { display } = await loadMockNpm(t, { config }) - t.equal(!!display.length, expectedDisplay, 'display') - t.equal(!!display.timing.length, expectedTiming, 'timing display') + const { logs } = await loadMockNpm(t, { config }) + t.equal(!!logs.length, expectedDisplay, 'display') + t.equal(!!logs.timing.length, expectedTiming, 'timing display') }) } }) -t.test('output clears progress and console.logs cleaned messages', async t => { - t.plan(4) - let showingProgress = true - const logs = [] - const errors = [] - const { npm } = await loadMockNpm(t, { - load: false, - mocks: { - npmlog: { - clearProgress: () => showingProgress = false, - showProgress: () => showingProgress = true, - }, - }, - globals: { - 'console.log': (...args) => { - t.equal(showingProgress, false, 'should not be showing progress right now') - logs.push(args) - }, - 'console.error': (...args) => { - t.equal(showingProgress, false, 'should not be showing progress right now') - errors.push(args) - }, - }, - }) - npm.originalOutput('hello\x00world') - npm.originalOutputError('error\x00world') - - t.match(logs, [['hello^@world']]) - t.match(errors, [['error^@world']]) -}) - t.test('aliases and typos', async t => { const { Npm } = await loadMockNpm(t, { init: false }) t.throws(() => Npm.cmd('thisisnotacommand'), { code: 'EUNKNOWNCOMMAND' }) @@ -580,13 +435,8 @@ t.test('explicit workspace rejection', async t => { workspaces: ['./packages/a'], }), }, - globals: { - 'process.argv': [ - process.execPath, - process.argv[1], - '--color', 'false', - '--workspace', './packages/a', - ], + config: { + workspace: './packages/a', }, }) await t.rejects( @@ -614,13 +464,8 @@ t.test('implicit workspace rejection', async t => { }), }, chdir: ({ prefix }) => join(prefix, 'packages', 'a'), - globals: { - 'process.argv': [ - process.execPath, - process.argv[1], - '--color', 'false', - '--workspace', './packages/a', - ], + config: { + workspace: './packages/a', }, }) await t.rejects( @@ -648,13 +493,6 @@ t.test('implicit workspace accept', async t => { }), }, chdir: ({ prefix }) => join(prefix, 'packages', 'a'), - globals: { - 'process.argv': [ - process.execPath, - process.argv[1], - '--color', 'false', - ], - }, }) await t.rejects(mock.npm.exec('org', []), /.*Usage/) }) diff --git a/deps/npm/test/lib/utils/audit-error.js b/deps/npm/test/lib/utils/audit-error.js index f6be56a152f710..9d6192fbc31be2 100644 --- a/deps/npm/test/lib/utils/audit-error.js +++ b/deps/npm/test/lib/utils/audit-error.js @@ -1,11 +1,9 @@ const t = require('tap') -const mockLogs = require('../../fixtures/mock-logs') const mockNpm = require('../../fixtures/mock-npm') const tmock = require('../../fixtures/tmock') const auditError = async (t, { command, error, ...config } = {}) => { - const { logs, logMocks } = mockLogs() - const mockAuditError = tmock(t, '{LIB}/utils/audit-error', logMocks) + const mockAuditError = tmock(t, '{LIB}/utils/audit-error') const mock = await mockNpm(t, { command, @@ -23,7 +21,7 @@ const auditError = async (t, { command, error, ...config } = {}) => { return { ...res, - logs: logs.warn.filter((l) => l[0] === 'audit'), + logs: mock.logs.warn.byTitle('audit'), output: mock.joinedOutput(), } } @@ -80,7 +78,7 @@ t.test('error, audit command, not json', async t => { t.ok(error, 'throws error') t.match(output, 'body error text', 'some output') - t.strictSame(logs, [['audit', 'message']], 'some warnings') + t.strictSame(logs, ['audit message'], 'some warnings') }) t.test('error, audit command, json', async t => { @@ -117,5 +115,5 @@ t.test('error, audit command, json', async t => { ' }\n' + '}' , 'some output') - t.strictSame(logs, [['audit', 'message']], 'some warnings') + t.strictSame(logs, ['audit message'], 'some warnings') }) diff --git a/deps/npm/test/lib/utils/display.js b/deps/npm/test/lib/utils/display.js index 2b9db0e6725100..33f9360e5728cf 100644 --- a/deps/npm/test/lib/utils/display.js +++ b/deps/npm/test/lib/utils/display.js @@ -1,161 +1,199 @@ const t = require('tap') -const log = require('../../../lib/utils/log-shim') +const timers = require('node:timers/promises') +const tmock = require('../../fixtures/tmock') const mockLogs = require('../../fixtures/mock-logs') const mockGlobals = require('@npmcli/mock-globals') -const tmock = require('../../fixtures/tmock') -const util = require('util') +const { inspect } = require('util') + +const mockDisplay = async (t, { mocks, load } = {}) => { + const procLog = require('proc-log') -const mockDisplay = (t, mocks) => { - const { logs, logMocks } = mockLogs(mocks) - const Display = tmock(t, '{LIB}/utils/display', { - ...mocks, - ...logMocks, + const logs = mockLogs() + + const Display = tmock(t, '{LIB}/utils/display', mocks) + const display = new Display(logs.streams) + const displayLoad = async (opts) => display.load({ + loglevel: 'silly', + stderrColor: false, + stdoutColot: false, + heading: 'npm', + ...opts, }) - const display = new Display() + + if (load !== false) { + await displayLoad(load) + } + t.teardown(() => display.off()) - return { display, logs } + return { + ...procLog, + display, + displayLoad, + ...logs.logs, + } } -t.test('setup', async (t) => { - const { display } = mockDisplay(t) +t.test('can log cleanly', async (t) => { + const { log, logs } = await mockDisplay(t) - display.load({ timing: true, loglevel: 'notice' }) - t.equal(log.level, 'notice') + log.error('', 'test\x00message') + t.match(logs.error, ['test^@message']) +}) - display.load({ timing: false, loglevel: 'notice' }) - t.equal(log.level, 'notice') +t.test('can handle special eresolves', async (t) => { + const explains = [] + const { log, logs } = await mockDisplay(t, { + mocks: { + '{LIB}/utils/explain-eresolve.js': { + explain: (...args) => { + explains.push(args) + return 'EXPLAIN' + }, + }, + }, + }) - display.load({ color: true }) - t.equal(log.useColor(), true) + log.warn('ERESOLVE', 'hello', { some: 'object' }) + t.strictSame(logs.warn, ['ERESOLVE hello', 'EXPLAIN']) + t.match(explains, [[{ some: 'object' }, Function, 2]]) +}) - display.load({ unicode: true }) - t.equal(log.gauge._theme.hasUnicode, true) +t.test('can buffer output when paused', async t => { + const { displayLoad, outputs, output } = await mockDisplay(t, { + load: false, + }) - display.load({ unicode: false }) - t.equal(log.gauge._theme.hasUnicode, false) + output.buffer('Message 1') + output.standard('Message 2') - mockGlobals(t, { 'process.stderr.isTTY': true }) - display.load({ progress: true }) - t.equal(log.progressEnabled, true) + t.strictSame(outputs, []) + await displayLoad() + t.strictSame(outputs, ['Message 1', 'Message 2']) }) -t.test('can log cleanly', async (t) => { - const explains = [] - const { display, logs } = mockDisplay(t, { - npmlog: { - error: (...args) => logs.push(['error', ...args]), - warn: (...args) => logs.push(['warn', ...args]), - }, - '{LIB}/utils/explain-eresolve.js': { - explain: (...args) => { - explains.push(args) - return 'explanation' - }, +t.test('can do progress', async (t) => { + const { log, logs, outputs, outputErrors, output, input } = await mockDisplay(t, { + load: { + progress: true, }, }) - display.log('error', 'test\x00message') - t.match(logs.error, [['test^@message']]) + // wait for initial timer interval to load + await timers.setTimeout(200) + + log.error('', 'before input') + output.standard('before input') - display.log('warn', 'ERESOLVE', 'hello', { some: 'object' }) - t.match(logs.warn, [['ERESOLVE', 'hello']]) - t.match(explains, [[{ some: 'object' }, null, 2]]) + const end = input.start() + log.error('', 'during input') + output.standard('during input') + end() + + // wait long enough for all spinner frames to render + await timers.setTimeout(800) + log.error('', 'after input') + output.standard('after input') + + t.strictSame([...new Set(outputErrors)].sort(), ['-', '/', '\\', '|']) + t.strictSame(logs, ['error before input', 'error during input', 'error after input']) + t.strictSame(outputs, ['before input', 'during input', 'after input']) }) t.test('handles log throwing', async (t) => { + class ThrowInspect { + #crashes = 0; + + [inspect.custom] () { + throw new Error(`Crashed ${++this.#crashes}`) + } + } + const errors = [] - mockGlobals(t, { - 'console.error': (...args) => errors.push(args), - }) - const { display } = mockDisplay(t, { - npmlog: { - verbose: () => { - throw new Error('verbose') - }, - }, - '{LIB}/utils/explain-eresolve.js': { - explain: () => { - throw new Error('explain') - }, - }, - }) + mockGlobals(t, { 'console.error': (...msg) => errors.push(msg) }) - display.log('warn', 'ERESOLVE', 'hello', { some: 'object' }) - t.match(errors, [ - [/attempt to log .* crashed/, Error('explain'), Error('verbose')], + const { log, logs } = await mockDisplay(t) + + log.error('woah', new ThrowInspect()) + + t.strictSame(logs.error, []) + t.equal(errors.length, 1) + t.match(errors[0], [ + 'attempt to log crashed', + new Error('Crashed 1'), + new Error('Crashed 2'), ]) }) -class CustomObj { - [util.inspect.custom] () { - return this.inspected - } -} +t.test('incorrect levels', async t => { + const { outputs } = await mockDisplay(t) + process.emit('output', 'not a real level') + t.strictSame(outputs, [], 'output is ignored') +}) t.test('Display.clean', async (t) => { - const Display = require('../../../lib/utils/display') - const customNaN = new CustomObj() - const customNull = new CustomObj() - const customNumber = new CustomObj() - const customObject = new CustomObj() - const customString = new CustomObj() - const customUndefined = new CustomObj() - customNaN.inspected = NaN - customNull.inspected = null - customNumber.inspected = 477 - customObject.inspected = { custom: 'rend\x00ering' } - customString.inspected = 'custom\x00rendering' - customUndefined.inspected = undefined - t.test('strings', async (t) => { - const tests = [ - [477, '477'], - [null, 'null'], - [NaN, 'NaN'], - [true, 'true'], - [undefined, 'undefined'], - ['🚀', '🚀'], - // Cover the bounds of each range and a few characters from inside each range - // \x00 through \x1f - ['hello\x00world', 'hello^@world'], - ['hello\x07world', 'hello^Gworld'], - ['hello\x1bworld', 'hello^[world'], - ['hello\x1eworld', 'hello^^world'], - ['hello\x1fworld', 'hello^_world'], - // \x7f is C0 - ['hello\x7fworld', 'hello^?world'], - // \x80 through \x9f - ['hello\x80world', 'hello^@world'], - ['hello\x87world', 'hello^Gworld'], - ['hello\x9eworld', 'hello^^world'], - ['hello\x9fworld', 'hello^_world'], - // Allowed C0 - ['hello\tworld', 'hello\tworld'], - ['hello\nworld', 'hello\nworld'], - ['hello\vworld', 'hello\vworld'], - ['hello\rworld', 'hello\rworld'], - // Allowed SGR - ['hello\x1b[38;5;254mworld', 'hello\x1b[38;5;254mworld'], - ['hello\x1b[mworld', 'hello\x1b[mworld'], - // Unallowed CSI / OSC - ['hello\x1b[2Aworld', 'hello^[[2Aworld'], - ['hello\x9b[2Aworld', 'hello^[[2Aworld'], - ['hello\x9decho goodbye\x9cworld', 'hello^]echo goodbye^\\world'], - // This is done twice to ensure we define inspect.custom as writable - [{ test: 'object' }, "{ test: 'object' }"], - [{ test: 'object' }, "{ test: 'object' }"], - // Make sure custom util.inspect doesn't bypass our cleaning - [customNaN, 'NaN'], - [customNull, 'null'], - [customNumber, '477'], - [customObject, "{ custom: 'rend\\x00ering' }"], - [customString, 'custom^@rendering'], - [customUndefined, 'undefined'], - // UTF-16 form of 8-bit C1 - ['hello\xc2\x9bworld', 'hello\xc2^[world'], - ] - for (const [dirty, clean] of tests) { - const cleaned = Display.clean(dirty) - t.equal(util.format(cleaned), clean) + const { output, outputs, clearOutput } = await mockDisplay(t) + + class CustomObj { + #inspected + + constructor (val) { + this.#inspected = val } - }) + + [inspect.custom] () { + return this.#inspected + } + } + + const tests = [ + [477, '477'], + [null, 'null'], + [NaN, 'NaN'], + [true, 'true'], + [undefined, 'undefined'], + ['🚀', '🚀'], + // Cover the bounds of each range and a few characters from inside each range + // \x00 through \x1f + ['hello\x00world', 'hello^@world'], + ['hello\x07world', 'hello^Gworld'], + ['hello\x1bworld', 'hello^[world'], + ['hello\x1eworld', 'hello^^world'], + ['hello\x1fworld', 'hello^_world'], + // \x7f is C0 + ['hello\x7fworld', 'hello^?world'], + // \x80 through \x9f + ['hello\x80world', 'hello^@world'], + ['hello\x87world', 'hello^Gworld'], + ['hello\x9eworld', 'hello^^world'], + ['hello\x9fworld', 'hello^_world'], + // Allowed C0 + ['hello\tworld', 'hello\tworld'], + ['hello\nworld', 'hello\nworld'], + ['hello\vworld', 'hello\vworld'], + ['hello\rworld', 'hello\rworld'], + // Allowed SGR + ['hello\x1b[38;5;254mworld', 'hello\x1b[38;5;254mworld'], + ['hello\x1b[mworld', 'hello\x1b[mworld'], + // Unallowed CSI / OSC + ['hello\x1b[2Aworld', 'hello^[[2Aworld'], + ['hello\x9b[2Aworld', 'hello^[[2Aworld'], + ['hello\x9decho goodbye\x9cworld', 'hello^]echo goodbye^\\world'], + // This is done twice to ensure we define inspect.custom as writable + [{ test: 'object' }, "{ test: 'object' }"], + // Make sure custom util.inspect doesn't bypass our cleaning + [new CustomObj(NaN), 'NaN'], + [new CustomObj(null), 'null'], + [new CustomObj(477), '477'], + [new CustomObj({ custom: 'rend\x00ering' }), "{ custom: 'rend\\x00ering' }"], + [new CustomObj('custom\x00rendering'), 'custom^@rendering'], + [new CustomObj(undefined), 'undefined'], + // UTF-16 form of 8-bit C1 + ['hello\xc2\x9bworld', 'hello\xc2^[world'], + ] + + for (const [dirty, clean] of tests) { + output.standard(dirty) + t.equal(outputs[0], clean) + clearOutput() + } }) diff --git a/deps/npm/test/lib/workspaces/get-workspaces.js b/deps/npm/test/lib/utils/get-workspaces.js similarity index 98% rename from deps/npm/test/lib/workspaces/get-workspaces.js rename to deps/npm/test/lib/utils/get-workspaces.js index 4e48b1c4b7707e..931f90d13046fd 100644 --- a/deps/npm/test/lib/workspaces/get-workspaces.js +++ b/deps/npm/test/lib/utils/get-workspaces.js @@ -1,6 +1,6 @@ const { resolve } = require('path') const t = require('tap') -const getWorkspaces = require('../../../lib/workspaces/get-workspaces.js') +const getWorkspaces = require('../../../lib/utils/get-workspaces.js') const normalizePath = p => p .replace(/\\+/g, '/') diff --git a/deps/npm/test/lib/utils/completion/installed-deep.js b/deps/npm/test/lib/utils/installed-deep.js similarity index 96% rename from deps/npm/test/lib/utils/completion/installed-deep.js rename to deps/npm/test/lib/utils/installed-deep.js index 0af26861ff83a5..20e001aaec751e 100644 --- a/deps/npm/test/lib/utils/completion/installed-deep.js +++ b/deps/npm/test/lib/utils/installed-deep.js @@ -1,6 +1,6 @@ const t = require('tap') -const installedDeep = require('../../../../lib/utils/completion/installed-deep.js') -const mockNpm = require('../../../fixtures/mock-npm') +const installedDeep = require('../../../lib/utils/installed-deep.js') +const mockNpm = require('../../fixtures/mock-npm') const fixture = { 'package.json': JSON.stringify({ diff --git a/deps/npm/test/lib/utils/completion/installed-shallow.js b/deps/npm/test/lib/utils/installed-shallow.js similarity index 89% rename from deps/npm/test/lib/utils/completion/installed-shallow.js rename to deps/npm/test/lib/utils/installed-shallow.js index 3666803979cb38..67b49292a64c78 100644 --- a/deps/npm/test/lib/utils/completion/installed-shallow.js +++ b/deps/npm/test/lib/utils/installed-shallow.js @@ -1,6 +1,6 @@ const t = require('tap') -const installed = require('../../../../lib/utils/completion/installed-shallow.js') -const mockNpm = require('../../../fixtures/mock-npm') +const installed = require('../../../lib/utils/installed-shallow.js') +const mockNpm = require('../../fixtures/mock-npm') const mockShallow = async (t, config) => { const res = await mockNpm(t, { diff --git a/deps/npm/test/lib/utils/log-file.js b/deps/npm/test/lib/utils/log-file.js index f34dda8f524337..8e07da8671b6ad 100644 --- a/deps/npm/test/lib/utils/log-file.js +++ b/deps/npm/test/lib/utils/log-file.js @@ -46,6 +46,8 @@ const loadLogFile = async (t, { buffer = [], mocks, testdir = {}, ...options } = const MockLogFile = tmock(t, '{LIB}/utils/log-file.js', mocks) const logFile = new MockLogFile(Object.keys(options).length ? options : undefined) + // Create a fake public method since there is not one on logFile anymore + logFile.log = (...b) => process.emit('log', ...b) buffer.forEach((b) => logFile.log(...b)) const id = getId() @@ -165,7 +167,7 @@ t.test('initial stream error', async t => { mocks: { 'fs-minipass': { WriteStreamSync: class { - constructor (...args) { + constructor () { throw new Error('no stream') } }, diff --git a/deps/npm/test/lib/utils/log-shim.js b/deps/npm/test/lib/utils/log-shim.js deleted file mode 100644 index 7c8fb7ce3c9569..00000000000000 --- a/deps/npm/test/lib/utils/log-shim.js +++ /dev/null @@ -1,101 +0,0 @@ -const t = require('tap') -const tmock = require('../../fixtures/tmock') - -const makeShim = (mocks) => tmock(t, '{LIB}/utils/log-shim.js', mocks) - -const loggers = [ - 'notice', - 'error', - 'warn', - 'info', - 'verbose', - 'http', - 'silly', - 'pause', - 'resume', -] - -t.test('has properties', (t) => { - const shim = makeShim() - - t.match(shim, { - level: String, - levels: {}, - gauge: {}, - stream: {}, - heading: undefined, - enableColor: Function, - disableColor: Function, - enableUnicode: Function, - disableUnicode: Function, - enableProgress: Function, - disableProgress: Function, - ...loggers.reduce((acc, l) => { - acc[l] = Function - return acc - }, {}), - }) - - t.match(Object.keys(shim).sort(), [ - 'level', - 'heading', - 'levels', - 'gauge', - 'stream', - 'tracker', - 'useColor', - 'enableColor', - 'disableColor', - 'enableUnicode', - 'disableUnicode', - 'enableProgress', - 'disableProgress', - 'progressEnabled', - 'clearProgress', - 'showProgress', - 'newItem', - 'newGroup', - ...loggers, - ].sort()) - - t.end() -}) - -t.test('works with npmlog/proclog proxy', t => { - const procLog = { silly: () => 'SILLY' } - const npmlog = { level: 'woo', enableColor: () => true } - const shim = makeShim({ npmlog, 'proc-log': procLog }) - - t.equal(shim.level, 'woo', 'can get a property') - - npmlog.level = 'hey' - t.strictSame( - [shim.level, npmlog.level], - ['hey', 'hey'], - 'can get a property after update on npmlog' - ) - - shim.level = 'test' - t.strictSame( - [shim.level, npmlog.level], - ['test', 'test'], - 'can get a property after update on shim' - ) - - t.ok(shim.enableColor(), 'can call method on shim to call npmlog') - t.equal(shim.silly(), 'SILLY', 'can call method on proclog') - t.notOk(shim.LEVELS, 'only includes levels from npmlog') - t.throws(() => shim.gauge = 100, 'cant set getters properies') - - t.end() -}) - -t.test('works with npmlog/proclog proxy', t => { - const shim = makeShim() - - loggers.forEach((k) => { - t.doesNotThrow(() => shim[k]('test')) - }) - - t.end() -}) diff --git a/deps/npm/test/lib/utils/otplease.js b/deps/npm/test/lib/utils/otplease.js index d788c39da842c5..6dc3ee0f0b069d 100644 --- a/deps/npm/test/lib/utils/otplease.js +++ b/deps/npm/test/lib/utils/otplease.js @@ -119,7 +119,7 @@ t.test('prompts for otp for 401', async (t) => { }) t.test('does not prompt for non-otp errors', async (t) => { - const fn = async (opts) => { + const fn = async () => { throw new Error('nope') } @@ -132,7 +132,7 @@ t.test('does not prompt for non-otp errors', async (t) => { }) t.test('does not prompt if stdin or stdout is not a tty', async (t) => { - const fn = async (opts) => { + const fn = async () => { throw Object.assign(new Error('nope'), { code: 'EOTP' }) } diff --git a/deps/npm/test/lib/utils/pulse-till-done.js b/deps/npm/test/lib/utils/pulse-till-done.js deleted file mode 100644 index 3b3f4b2f2253ef..00000000000000 --- a/deps/npm/test/lib/utils/pulse-till-done.js +++ /dev/null @@ -1,35 +0,0 @@ -const t = require('tap') -const tmock = require('../../fixtures/tmock') - -let pulseStarted = null - -const pulseTillDone = tmock(t, '{LIB}/utils/pulse-till-done.js', { - npmlog: { - gauge: { - pulse: () => { - if (pulseStarted) { - pulseStarted() - } - }, - }, - }, -}) - -t.test('pulses (with promise)', async (t) => { - t.teardown(() => { - pulseStarted = null - }) - - let resolver - const promise = new Promise(resolve => { - resolver = resolve - }) - - const result = pulseTillDone.withPromise(promise) - // wait until the gauge has fired at least once - await new Promise(resolve => { - pulseStarted = resolve - }) - resolver('value') - t.resolveMatch(result, 'value', 'returned the resolved promise') -}) diff --git a/deps/npm/test/lib/utils/read-user-info.js b/deps/npm/test/lib/utils/read-user-info.js index a1c2f980cf745b..35628f7f2faac5 100644 --- a/deps/npm/test/lib/utils/read-user-info.js +++ b/deps/npm/test/lib/utils/read-user-info.js @@ -1,41 +1,45 @@ const t = require('tap') +const procLog = require('proc-log') const tmock = require('../../fixtures/tmock') let readOpts = null let readResult = null -const read = { read: async (opts) => { - readOpts = opts - return readResult -} } - -const npmUserValidate = { - username: (username) => { - if (username === 'invalid') { - return new Error('invalid username') - } - - return null - }, - email: (email) => { - if (email.startsWith('invalid')) { - return new Error('invalid email') - } - - return null - }, -} - let logMsg = null + const readUserInfo = tmock(t, '{LIB}/utils/read-user-info.js', { - read, - npmlog: { - clearProgress: () => {}, - showProgress: () => {}, + read: { + read: async (opts) => { + readOpts = opts + return readResult + }, }, 'proc-log': { - warn: (msg) => logMsg = msg, + ...procLog, + log: { + ...procLog.log, + warn: (msg) => logMsg = msg, + }, + input: { + ...procLog.input, + read: (fn) => fn(), + }, + }, + 'npm-user-validate': { + username: (username) => { + if (username === 'invalid') { + return new Error('invalid username') + } + + return null + }, + email: (email) => { + if (email.startsWith('invalid')) { + return new Error('invalid email') + } + + return null + }, }, - 'npm-user-validate': npmUserValidate, }) t.beforeEach(() => { diff --git a/deps/npm/test/lib/utils/reify-output.js b/deps/npm/test/lib/utils/reify-output.js index fd15e25a749842..205b7baf421f79 100644 --- a/deps/npm/test/lib/utils/reify-output.js +++ b/deps/npm/test/lib/utils/reify-output.js @@ -8,7 +8,18 @@ const mockReify = async (t, reify, { command, ...config } = {}) => { const mock = await mockNpm(t, { command, config, - setCmd: true, + }) + + // Hack to adapt existing fake test. Make npm.command + // return whatever was passed in to this function. + // What it should be doing is npm.exec(command) but that + // breaks most of these tests because they dont expect + // a command to actually run. + Object.defineProperty(mock.npm, 'command', { + get () { + return command + }, + enumerable: true, }) reifyOutput(mock.npm, reify) diff --git a/deps/npm/test/lib/utils/tar.js b/deps/npm/test/lib/utils/tar.js index 274bad95c0af3f..45ba720ac54edb 100644 --- a/deps/npm/test/lib/utils/tar.js +++ b/deps/npm/test/lib/utils/tar.js @@ -9,14 +9,16 @@ t.cleanSnapshot = data => cleanZlib(data) const mockTar = ({ notice }) => tmock(t, '{LIB}/utils/tar.js', { 'proc-log': { - notice, + log: { + notice, + }, }, }) const printLogs = (tarball, options) => { const logs = [] const { logTar } = mockTar({ - notice: (...args) => args.map(el => logs.push(el)), + notice: (...args) => logs.push(...args), }) logTar(tarball, options) return logs.join('\n') diff --git a/deps/npm/test/lib/utils/timers.js b/deps/npm/test/lib/utils/timers.js index 74df6c28cd361c..4e5bfb104db975 100644 --- a/deps/npm/test/lib/utils/timers.js +++ b/deps/npm/test/lib/utils/timers.js @@ -1,86 +1,58 @@ const t = require('tap') const { resolve, join } = require('path') const fs = require('graceful-fs') -const mockLogs = require('../../fixtures/mock-logs') +const { log, time } = require('proc-log') const tmock = require('../../fixtures/tmock') -const mockTimers = (t, options) => { - const { logs, logMocks } = mockLogs() - const Timers = tmock(t, '{LIB}/utils/timers', { - ...logMocks, +const mockTimers = (t) => { + const logs = log.LEVELS.reduce((acc, l) => { + acc[l] = [] + return acc + }, {}) + const logHandler = (level, ...args) => { + logs[level].push(args.join(' ')) + } + process.on('log', logHandler) + const Timers = tmock(t, '{LIB}/utils/timers') + const timers = new Timers() + t.teardown(() => { + timers.off() + process.off('log', logHandler) }) - const timers = new Timers(options) - t.teardown(() => timers.off()) return { timers, logs } } -t.test('getters', async (t) => { - const { timers } = mockTimers(t) - t.match(timers.unfinished, new Map()) - t.match(timers.finished, {}) -}) - -t.test('listens/stops on process', async (t) => { - const { timers } = mockTimers(t) - process.emit('time', 'foo') - process.emit('time', 'bar') - process.emit('timeEnd', 'bar') - t.match(timers.unfinished, new Map([['foo', Number]])) - t.match(timers.finished, { bar: Number }) +t.test('logs timing events', async (t) => { + const { timers, logs } = mockTimers(t) + time.start('foo') + time.start('bar') + time.end('bar') timers.off() - process.emit('time', 'baz') - t.notOk(timers.unfinished.get('baz')) -}) - -t.test('convenience time method', async (t) => { - const { timers } = mockTimers(t) - - const end = timers.time('later') - timers.time('sync', () => {}) - await timers.time('async', () => new Promise(r => setTimeout(r, 10))) - end() - - t.match(timers.finished, { later: Number, sync: Number, async: Number }) -}) - -t.test('initial timer', async (t) => { - const { timers } = mockTimers(t, { start: 'foo' }) - process.emit('timeEnd', 'foo') - t.match(timers.finished, { foo: Number }) -}) - -t.test('initial listener', async (t) => { - const events = [] - const listener = (...args) => events.push(args) - const { timers } = mockTimers(t, { listener }) - process.emit('time', 'foo') - process.emit('time', 'bar') - process.emit('timeEnd', 'bar') - timers.off(listener) - process.emit('timeEnd', 'foo') - t.equal(events.length, 1) - t.match(events, [['bar', Number]]) + time.end('foo') + t.equal(logs.timing.length, 1) + t.match(logs.timing[0], /^bar Completed in [0-9]ms/) }) t.test('finish unstarted timer', async (t) => { const { logs } = mockTimers(t) - process.emit('timeEnd', 'foo') - t.match(logs.silly, [['timing', /^Tried to end timer/, 'foo']]) + time.end('foo') + t.match(logs.silly, ["timing Tried to end timer that doesn't exist: foo"]) }) t.test('writes file', async (t) => { const { timers } = mockTimers(t) const dir = t.testdir() - process.emit('time', 'foo') - process.emit('timeEnd', 'foo') - timers.load({ path: resolve(dir, `TIMING_FILE-`) }) - timers.writeFile({ some: 'data' }) + time.start('foo') + time.end('foo') + time.start('ohno') + timers.load({ timing: true, path: resolve(dir, `TIMING_FILE-`) }) + timers.finish({ some: 'data' }) const data = JSON.parse(fs.readFileSync(resolve(dir, 'TIMING_FILE-timing.json'))) t.match(data, { metadata: { some: 'data' }, - timers: { foo: Number }, + timers: { foo: Number, npm: Number }, unfinishedTimers: { - npm: [Number, Number], + ohno: [Number, Number], }, }) }) @@ -89,19 +61,18 @@ t.test('fails to write file', async (t) => { const { logs, timers } = mockTimers(t) const dir = t.testdir() - timers.load({ path: join(dir, 'does', 'not', 'exist') }) - timers.writeFile() + timers.load({ timing: true, path: join(dir, 'does', 'not', 'exist') }) + timers.finish() - t.match(logs.warn, [['timing', 'could not write timing file']]) - t.equal(timers.file, null) + t.match(logs.warn, ['timing could not write timing file:']) }) t.test('no dir and no file', async (t) => { const { logs, timers } = mockTimers(t) timers.load() - timers.writeFile() + timers.finish() - t.strictSame(logs, []) - t.equal(timers.file, null) + t.strictSame(logs.warn, []) + t.strictSame(logs.silly, []) }) diff --git a/deps/npm/test/lib/utils/web-auth.js b/deps/npm/test/lib/utils/web-auth.js index a4e8f4bbc755dc..ec8c1d17e9fa1f 100644 --- a/deps/npm/test/lib/utils/web-auth.js +++ b/deps/npm/test/lib/utils/web-auth.js @@ -21,8 +21,8 @@ t.test('returns token on success', async (t) => { t.test('closes opener when auth check finishes', async (t) => { const opener = (_url, emitter) => { - return new Promise((resolve, reject) => { - // the only way to finish this promise is to emit aboter on the emitter + return new Promise((resolve) => { + // the only way to finish this promise is to emit abort on the emitter emitter.addListener('abort', () => { resolve() }) diff --git a/deps/simdutf/simdutf.cpp b/deps/simdutf/simdutf.cpp index 13c408263e7ac4..84e4459cf6b97a 100644 --- a/deps/simdutf/simdutf.cpp +++ b/deps/simdutf/simdutf.cpp @@ -1,4 +1,4 @@ -/* auto-generated on 2024-04-11 09:56:55 -0400. Do not edit! */ +/* auto-generated on 2024-05-07 22:33:11 -0400. Do not edit! */ /* begin file src/simdutf.cpp */ #include "simdutf.h" // We include base64_tables once. @@ -1031,9 +1031,9 @@ namespace { return vget_lane_u64(vreinterpret_u64_u8(vshrn_n_u16(vreinterpretq_u16_u8(*this), 4)), 0); } - simdutf_really_inline bool any() const { return vmaxvq_u8(*this) != 0; } - simdutf_really_inline bool none() const { return vmaxvq_u8(*this) == 0; } - simdutf_really_inline bool all() const { return vminvq_u8(*this) == 0xFF; } + simdutf_really_inline bool any() const { return vmaxvq_u32(vreinterpretq_u32_u8(*this)) != 0; } + simdutf_really_inline bool none() const { return vmaxvq_u32(vreinterpretq_u32_u8(*this)) == 0; } + simdutf_really_inline bool all() const { return vminvq_u32(vreinterpretq_u32_u8(*this)) == 0xFFFFF; } }; @@ -2481,10 +2481,10 @@ namespace simd { struct simd8: base8 { static simdutf_really_inline simd8 splat(bool _value) { return _mm256_set1_epi8(uint8_t(-(!!_value))); } - simdutf_really_inline simd8() : base8() {} - simdutf_really_inline simd8(const __m256i _value) : base8(_value) {} + simdutf_really_inline simd8() : base8() {} + simdutf_really_inline simd8(const __m256i _value) : base8(_value) {} // Splat constructor - simdutf_really_inline simd8(bool _value) : base8(splat(_value)) {} + simdutf_really_inline simd8(bool _value) : base8(splat(_value)) {} simdutf_really_inline uint32_t to_bitmask() const { return uint32_t(_mm256_movemask_epi8(*this)); } simdutf_really_inline bool any() const { return !_mm256_testz_si256(*this, *this); } @@ -3409,10 +3409,10 @@ namespace simd { struct simd8: base8 { static simdutf_really_inline simd8 splat(bool _value) { return _mm_set1_epi8(uint8_t(-(!!_value))); } - simdutf_really_inline simd8() : base8() {} - simdutf_really_inline simd8(const __m128i _value) : base8(_value) {} + simdutf_really_inline simd8() : base8() {} + simdutf_really_inline simd8(const __m128i _value) : base8(_value) {} // Splat constructor - simdutf_really_inline simd8(bool _value) : base8(splat(_value)) {} + simdutf_really_inline simd8(bool _value) : base8(splat(_value)) {} simdutf_really_inline int to_bitmask() const { return _mm_movemask_epi8(*this); } simdutf_really_inline bool any() const { return !_mm_testz_si128(*this, *this); } @@ -4319,11 +4319,11 @@ template <> struct simd8 : base8 { return (__m128i)vec_splats((unsigned char)(-(!!_value))); } - simdutf_really_inline simd8() : base8() {} - simdutf_really_inline simd8(const __m128i _value) + simdutf_really_inline simd8() : base8() {} + simdutf_really_inline simd8(const __m128i _value) : base8(_value) {} // Splat constructor - simdutf_really_inline simd8(bool _value) + simdutf_really_inline simd8(bool _value) : base8(splat(_value)) {} simdutf_really_inline int to_bitmask() const { @@ -5999,8 +5999,8 @@ static const implementation* get_single_implementation() { */ class detect_best_supported_implementation_on_first_use final : public implementation { public: - const std::string &name() const noexcept final { return set_best()->name(); } - const std::string &description() const noexcept final { return set_best()->description(); } + std::string name() const noexcept final { return set_best()->name(); } + std::string description() const noexcept final { return set_best()->description(); } uint32_t required_instruction_sets() const noexcept final { return set_best()->required_instruction_sets(); } simdutf_warn_unused int detect_encodings(const char * input, size_t length) const noexcept override { @@ -6333,6 +6333,8 @@ class detect_best_supported_implementation_on_first_use final : public implement const implementation *set_best() const noexcept; }; +static_assert(std::is_trivially_destructible::value, "detect_best_supported_implementation_on_first_use should be trivially destructible"); + static const std::initializer_list& get_available_implementation_pointers() { static const std::initializer_list available_implementation_pointers { #if SIMDUTF_IMPLEMENTATION_ICELAKE @@ -6695,7 +6697,11 @@ class unsupported_implementation final : public implementation { unsupported_implementation() : implementation("unsupported", "Unsupported CPU (no detected SIMD instructions)", 0) {} }; -const unsupported_implementation unsupported_singleton{}; +const unsupported_implementation* get_unsupported_singleton() { + static const unsupported_implementation unsupported_singleton{}; + return &unsupported_singleton; +} +static_assert(std::is_trivially_destructible::value, "unsupported_singleton should be trivially destructible"); size_t available_implementation_list::size() const noexcept { return internal::get_available_implementation_pointers().size(); @@ -6713,7 +6719,7 @@ const implementation *available_implementation_list::detect_best_supported() con uint32_t required_instruction_sets = impl->required_instruction_sets(); if ((supported_instruction_sets & required_instruction_sets) == required_instruction_sets) { return impl; } } - return &unsupported_singleton; // this should never happen? + return get_unsupported_singleton(); // this should never happen? } const implementation *detect_best_supported_implementation_on_first_use::set_best() const noexcept { @@ -6728,7 +6734,7 @@ const implementation *detect_best_supported_implementation_on_first_use::set_bes return get_active_implementation() = force_implementation; } else { // Note: abort() and stderr usage within the library is forbidden. - return get_active_implementation() = &unsupported_singleton; + return get_active_implementation() = get_unsupported_singleton(); } } return get_active_implementation() = get_available_implementations().detect_best_supported(); @@ -6747,8 +6753,8 @@ SIMDUTF_DLLIMPORTEXPORT const internal::available_implementation_list& get_avail } /** - * The active implementation. - */ + * The active implementation. + */ SIMDUTF_DLLIMPORTEXPORT internal::atomic_ptr& get_active_implementation() { #if SIMDUTF_SINGLE_IMPLEMENTATION // skip runtime detection @@ -26119,7 +26125,7 @@ std::pair avx2_convert_utf16_to_utf8_with_errors(const char16_t* 1. an input register contains no surrogates and each value is in range 0x0000 .. 0x07ff. 2. an input register contains no surrogates and values are - is in range 0x0000 .. 0xffff. + in range 0x0000 .. 0xffff. 3. an input register contains surrogates --- i.e. codepoints can have 16 or 32 bits. @@ -32395,6 +32401,8 @@ simdutf_warn_unused size_t implementation::convert_valid_utf8_to_utf32(const cha /* end file src/rvv/rvv_utf8_to.inl.cpp */ /* begin file src/rvv/rvv_utf16_to.inl.cpp */ +#include + template simdutf_really_inline static result rvv_utf16_to_latin1_with_errors(const char16_t *src, size_t len, char *dst) { const char16_t *const beg = src; @@ -32609,47 +32617,95 @@ simdutf_really_inline static result rvv_utf16_to_utf32_with_errors(const char16_ const char16_t *const srcBeg = src; char32_t *const dstBeg = dst; + constexpr const uint16_t ANY_SURROGATE_MASK = 0xf800; + constexpr const uint16_t ANY_SURROGATE_VALUE = 0xd800; + constexpr const uint16_t LO_SURROGATE_MASK = 0xfc00; + constexpr const uint16_t LO_SURROGATE_VALUE = 0xdc00; + constexpr const uint16_t HI_SURROGATE_MASK = 0xfc00; + constexpr const uint16_t HI_SURROGATE_VALUE = 0xd800; + uint16_t last = 0; - for (size_t vl, vlOut; len > 0; len -= vl, src += vl, dst += vlOut, last = simdutf_byteflip(src[-1])) { - vl = __riscv_vsetvl_e16m2(len); - vuint16m2_t v1 = __riscv_vle16_v_u16m2((uint16_t const*)src, vl); - v1 = simdutf_byteflip(v1, vl); - vuint16m2_t v0 = __riscv_vslide1up_vx_u16m2(v1, last, vl); + while (len > 0) { + size_t vl = __riscv_vsetvl_e16m2(len); + vuint16m2_t v0 = __riscv_vle16_v_u16m2((uint16_t const*)src, vl); + v0 = simdutf_byteflip(v0, vl); + + { // check fast-path + const vuint16m2_t v = __riscv_vand_vx_u16m2(v0, ANY_SURROGATE_MASK, vl); + const vbool8_t any_surrogate = __riscv_vmseq_vx_u16m2_b8(v, ANY_SURROGATE_VALUE, vl); + if (__riscv_vfirst_m_b8(any_surrogate, vl) < 0) { + /* no surrogates */ + __riscv_vse32_v_u32m4((uint32_t*)dst, __riscv_vzext_vf2_u32m4(v0, vl), vl); + len -= vl; + src += vl; + dst += vl; + continue; + } + } - vbool8_t surhi0 = __riscv_vmseq_vx_u16m2_b8(__riscv_vand_vx_u16m2(v0, 0xFC00, vl), 0xD800, vl); - vbool8_t surlo1 = __riscv_vmseq_vx_u16m2_b8(__riscv_vand_vx_u16m2(v1, 0xFC00, vl), 0xDC00, vl); + if ((simdutf_byteflip(src[0]) & LO_SURROGATE_MASK) == LO_SURROGATE_VALUE) { + return result(error_code::SURROGATE, src - srcBeg); + } - /* no surrogates */ - if (__riscv_vfirst_m_b8(__riscv_vmor_mm_b8(surhi0, surlo1, vl), vl) < 0) { - vlOut = vl; - __riscv_vse32_v_u32m4((uint32_t*)dst, __riscv_vzext_vf2_u32m4(v1, vl), vl); - continue; + // decode surrogates + vuint16m2_t v1 = __riscv_vslide1down_vx_u16m2(v0, 0, vl); + vl = __riscv_vsetvl_e16m2(vl - 1); + if (vl == 0) { + return result(error_code::SURROGATE, src - srcBeg); } - long idx = __riscv_vfirst_m_b8(__riscv_vmxor_mm_b8(surhi0, surlo1, vl), vl); - if (idx >= 0) { - last = idx > 0 ? simdutf_byteflip(src[idx-1]) : last; - return result(error_code::SURROGATE, src - srcBeg + idx - (last - 0xD800u < 0x400u)); + const vbool8_t surhi = __riscv_vmseq_vx_u16m2_b8(__riscv_vand_vx_u16m2(v0, HI_SURROGATE_MASK, vl), HI_SURROGATE_VALUE, vl); + const vbool8_t surlo = __riscv_vmseq_vx_u16m2_b8(__riscv_vand_vx_u16m2(v1, LO_SURROGATE_MASK, vl), LO_SURROGATE_VALUE, vl); + + // compress everything but lo surrogates + const vbool8_t compress = __riscv_vmsne_vx_u16m2_b8(__riscv_vand_vx_u16m2(v0, LO_SURROGATE_MASK, vl), LO_SURROGATE_VALUE, vl); + + { + const vbool8_t diff = __riscv_vmxor_mm_b8(surhi, surlo, vl); + const long idx = __riscv_vfirst_m_b8(diff, vl); + if (idx >= 0) { + return result(error_code::SURROGATE, src - srcBeg + idx + 1); + } } - vbool8_t surhi1 = __riscv_vmseq_vx_u16m2_b8(__riscv_vand_vx_u16m2(v1, 0xFC00, vl), 0xD800, vl); - uint16_t next = vl < len ? simdutf_byteflip(src[vl]) : 0; + last = simdutf_byteflip(src[vl]); + vuint32m4_t utf32 = __riscv_vzext_vf2_u32m4(v0, vl); + + // v0 = 110110yyyyyyyyyy (0xd800 + yyyyyyyyyy) --- hi surrogate + // v1 = 110111xxxxxxxxxx (0xdc00 + xxxxxxxxxx) --- lo surrogate + + // t0 = u16( 0000_00yy_yyyy_yyyy) + const vuint32m4_t t0 = __riscv_vzext_vf2_u32m4(__riscv_vand_vx_u16m2(v0, 0x03ff, vl), vl); + // t1 = u32(0000_0000_0000_yyyy_yyyy_yy00_0000_0000) + const vuint32m4_t t1 = __riscv_vsll_vx_u32m4(t0, 10, vl); + + // t2 = u32(0000_0000_0000_0000_0000_00xx_xxxx_xxxx) + const vuint32m4_t t2 = __riscv_vzext_vf2_u32m4(__riscv_vand_vx_u16m2(v1, 0x03ff, vl), vl); + + // t3 = u32(0000_0000_0000_yyyy_yyyy_yyxx_xxxx_xxxx) + const vuint32m4_t t3 = __riscv_vor_vv_u32m4(t1, t2, vl); - vuint32m4_t wide = __riscv_vzext_vf2_u32m4(v1, vl); - vuint32m4_t slided = __riscv_vslide1down_vx_u32m4(wide, next, vl); - vuint32m4_t aligned = __riscv_vsll_vx_u32m4_mu(surhi1, wide, wide, 10, vl); - vuint32m4_t added = __riscv_vadd_vv_u32m4_mu(surhi1, aligned, aligned, slided, vl); - vuint32m4_t utf32 = __riscv_vadd_vx_u32m4_mu(surhi1, added, added, 0xFCA02400, vl); - vbool8_t m = __riscv_vmnot_m_b8(surlo1, vl); - vlOut = __riscv_vcpop_m_b8(m, vl); - vuint32m4_t comp = __riscv_vcompress_vm_u32m4(utf32, m, vl); + // t4 = utf32 from surrogate pairs + const vuint32m4_t t4 = __riscv_vadd_vx_u32m4(t3, 0x10000, vl); + + const vuint32m4_t result = __riscv_vmerge_vvm_u32m4(utf32, t4, surhi, vl); + + const vuint32m4_t comp = __riscv_vcompress_vm_u32m4(result, compress, vl); + const size_t vlOut = __riscv_vcpop_m_b8(compress, vl); __riscv_vse32_v_u32m4((uint32_t*)dst, comp, vlOut); + + len -= vl; + src += vl; + dst += vlOut; + + if ((last & LO_SURROGATE_MASK) == LO_SURROGATE_VALUE) { + // last item is lo surrogate and got already consumed + len -= 1; + src += 1; + } } - if (last - 0xD800u < 0x400u) - return result(error_code::SURROGATE, src - srcBeg - 1); /* end on high surrogate */ - else - return result(error_code::SUCCESS, dst - dstBeg); + return result(error_code::SUCCESS, dst - dstBeg); } simdutf_warn_unused size_t implementation::convert_utf16le_to_utf32(const char16_t *src, size_t len, char32_t *dst) const noexcept { diff --git a/deps/simdutf/simdutf.h b/deps/simdutf/simdutf.h index 7a4a3a2cf45033..d37bd2c7db5be8 100644 --- a/deps/simdutf/simdutf.h +++ b/deps/simdutf/simdutf.h @@ -1,4 +1,4 @@ -/* auto-generated on 2024-04-11 09:56:55 -0400. Do not edit! */ +/* auto-generated on 2024-05-07 22:33:11 -0400. Do not edit! */ /* begin file include/simdutf.h */ #ifndef SIMDUTF_H #define SIMDUTF_H @@ -149,7 +149,7 @@ #define SIMDUTF_HAS_RVV_TARGET_REGION 1 #endif -#if __riscv_v_intrinsic >= 11000 && !(__GNUC__ == 13 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 0) +#if __riscv_v_intrinsic >= 11000 #define SIMDUTF_HAS_RVV_INTRINSICS 1 #endif @@ -594,7 +594,7 @@ SIMDUTF_DISABLE_UNDESIRED_WARNINGS #define SIMDUTF_SIMDUTF_VERSION_H /** The version of simdutf being used (major.minor.revision) */ -#define SIMDUTF_VERSION "5.2.4" +#define SIMDUTF_VERSION "5.2.8" namespace simdutf { enum { @@ -609,7 +609,7 @@ enum { /** * The revision (major.minor.REVISION) of simdutf being used. */ - SIMDUTF_VERSION_REVISION = 4 + SIMDUTF_VERSION_REVISION = 8 }; } // namespace simdutf @@ -682,6 +682,17 @@ POSSIBILITY OF SUCH DAMAGE. #endif +// RISC-V ISA detection utilities +#if SIMDUTF_IS_RISCV64 && defined(__linux__) +#include // for syscall +// We define these ourselves, for backwards compatibility +struct simdutf_riscv_hwprobe { int64_t key; uint64_t value; }; +#define simdutf_riscv_hwprobe(...) syscall(258, __VA_ARGS__) +#define SIMDUTF_RISCV_HWPROBE_KEY_IMA_EXT_0 4 +#define SIMDUTF_RISCV_HWPROBE_IMA_V (1 << 2) +#define SIMDUTF_RISCV_HWPROBE_EXT_ZVBB (1 << 17) +#endif // SIMDUTF_IS_RISCV64 && defined(__linux__) + namespace simdutf { namespace internal { @@ -716,16 +727,6 @@ static inline uint32_t detect_supported_architectures() { #elif SIMDUTF_IS_RISCV64 -#if defined(__linux__) -#include -// We define these our selfs, for backwards compatibility -struct simdutf_riscv_hwprobe { int64_t key; uint64_t value; }; -#define simdutf_riscv_hwprobe(...) syscall(258, __VA_ARGS__) -#define SIMDUTF_RISCV_HWPROBE_KEY_IMA_EXT_0 4 -#define SIMDUTF_RISCV_HWPROBE_IMA_V (1 << 2) -#define SIMDUTF_RISCV_HWPROBE_EXT_ZVBB (1 << 17) -#endif - static inline uint32_t detect_supported_architectures() { uint32_t host_isa = instruction_set::DEFAULT; #if SIMDUTF_IS_RVV @@ -744,6 +745,10 @@ static inline uint32_t detect_supported_architectures() { if (extensions & SIMDUTF_RISCV_HWPROBE_EXT_ZVBB) host_isa |= instruction_set::ZVBB; } +#endif +#if defined(RUN_IN_SPIKE_SIMULATOR) + // Proxy Kernel does not implement yet hwprobe syscall + host_isa |= instruction_set::RVV; #endif return host_isa; } @@ -2369,7 +2374,7 @@ simdutf_warn_unused size_t base64_length_from_binary(size_t length, base64_optio * @param length the length of the input in bytes * @param output the pointer to buffer that can hold the conversion result (should be at least base64_length_from_binary(length) bytes long) * @param options the base64 options to use, can be base64_default or base64_url, is base64_default by default. - * @return number of written bytes, will be equal to base64_length_from_binary(length) + * @return number of written bytes, will be equal to base64_length_from_binary(length, options) */ size_t binary_to_base64(const char * input, size_t length, char* output, base64_options options = base64_default) noexcept; @@ -2454,7 +2459,7 @@ class implementation { * * @return the name of the implementation, e.g. "haswell", "westmere", "arm64" */ - virtual const std::string &name() const { return _name; } + virtual std::string name() const { return std::string(_name); } /** * The description of this implementation. @@ -2464,7 +2469,7 @@ class implementation { * * @return the name of the implementation, e.g. "haswell", "westmere", "arm64" */ - virtual const std::string &description() const { return _description; } + virtual std::string description() const { return std::string(_description); } /** * The instruction sets this implementation is compiled against @@ -3594,7 +3599,7 @@ class implementation { * @param length the length of the input in bytes * @param output the pointer to buffer that can hold the conversion result (should be at least base64_length_from_binary(length) bytes long) * @param options the base64 options to use, can be base64_default or base64_url, is base64_default by default. - * @return number of written bytes, will be equal to base64_length_from_binary(length) + * @return number of written bytes, will be equal to base64_length_from_binary(length, options) */ virtual size_t binary_to_base64(const char * input, size_t length, char* output, base64_options options = base64_default) const noexcept = 0; @@ -3602,8 +3607,8 @@ class implementation { protected: /** @private Construct an implementation with the given name and description. For subclasses. */ simdutf_really_inline implementation( - std::string name, - std::string description, + const char* name, + const char* description, uint32_t required_instruction_sets ) : _name(name), @@ -3611,18 +3616,18 @@ class implementation { _required_instruction_sets(required_instruction_sets) { } - virtual ~implementation()=default; - +protected: + ~implementation() = default; private: /** * The name of this implementation. */ - const std::string _name; + const char* _name; /** * The description of this implementation. */ - const std::string _description; + const char* _description; /** * Instruction sets required for this implementation. diff --git a/deps/uvwasi/include/uvwasi.h b/deps/uvwasi/include/uvwasi.h index 752c3ba3958e7c..7dbcc667793a07 100644 --- a/deps/uvwasi/include/uvwasi.h +++ b/deps/uvwasi/include/uvwasi.h @@ -11,7 +11,7 @@ extern "C" { #define UVWASI_VERSION_MAJOR 0 #define UVWASI_VERSION_MINOR 0 -#define UVWASI_VERSION_PATCH 20 +#define UVWASI_VERSION_PATCH 21 #define UVWASI_VERSION_HEX ((UVWASI_VERSION_MAJOR << 16) | \ (UVWASI_VERSION_MINOR << 8) | \ (UVWASI_VERSION_PATCH)) diff --git a/deps/uvwasi/src/path_resolver.c b/deps/uvwasi/src/path_resolver.c index ec8946b1393d74..deb3f603821f92 100644 --- a/deps/uvwasi/src/path_resolver.c +++ b/deps/uvwasi/src/path_resolver.c @@ -269,7 +269,7 @@ static uvwasi_errno_t uvwasi__normalize_relative_path( normalized. */ uvwasi_errno_t err; char* combined; - char* normalized; + char* normalized = NULL; uvwasi_size_t combined_len; uvwasi_size_t fd_path_len; uvwasi_size_t norm_len; diff --git a/deps/uvwasi/src/uvwasi.c b/deps/uvwasi/src/uvwasi.c index 40162f886fa224..948c1355c9ccf7 100644 --- a/deps/uvwasi/src/uvwasi.c +++ b/deps/uvwasi/src/uvwasi.c @@ -1158,7 +1158,7 @@ uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi, offset, nread); - if (uvwasi == NULL || iovs == NULL || nread == NULL) + if (uvwasi == NULL || (iovs == NULL && iovs_len > 0) || nread == NULL || offset > INT64_MAX) return UVWASI_EINVAL; err = uvwasi_fd_table_get(uvwasi->fds, @@ -1169,6 +1169,14 @@ uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi, if (err != UVWASI_ESUCCESS) return err; + // libuv returns EINVAL in this case. To behave consistently with other + // Wasm runtimes, return OK here with a no-op. + if (iovs_len == 0) { + uv_mutex_unlock(&wrap->mutex); + *nread = 0; + return UVWASI_ESUCCESS; + } + err = uvwasi__setup_iovs(uvwasi, &bufs, iovs, iovs_len); if (err != UVWASI_ESUCCESS) { uv_mutex_unlock(&wrap->mutex); @@ -1282,7 +1290,7 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi, offset, nwritten); - if (uvwasi == NULL || iovs == NULL || nwritten == NULL) + if (uvwasi == NULL || (iovs == NULL && iovs_len > 0) || nwritten == NULL || offset > INT64_MAX) return UVWASI_EINVAL; err = uvwasi_fd_table_get(uvwasi->fds, @@ -1293,6 +1301,14 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi, if (err != UVWASI_ESUCCESS) return err; + // libuv returns EINVAL in this case. To behave consistently with other + // Wasm runtimes, return OK here with a no-op. + if (iovs_len == 0) { + uv_mutex_unlock(&wrap->mutex); + *nwritten = 0; + return UVWASI_ESUCCESS; + } + err = uvwasi__setup_ciovs(uvwasi, &bufs, iovs, iovs_len); if (err != UVWASI_ESUCCESS) { uv_mutex_unlock(&wrap->mutex); @@ -1332,14 +1348,21 @@ uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi, iovs, iovs_len, nread); - - if (uvwasi == NULL || iovs == NULL || nread == NULL) + if (uvwasi == NULL || (iovs == NULL && iovs_len > 0) || nread == NULL) return UVWASI_EINVAL; err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_READ, 0); if (err != UVWASI_ESUCCESS) return err; + // libuv returns EINVAL in this case. To behave consistently with other + // Wasm runtimes, return OK here with a no-op. + if (iovs_len == 0) { + uv_mutex_unlock(&wrap->mutex); + *nread = 0; + return UVWASI_ESUCCESS; + } + err = uvwasi__setup_iovs(uvwasi, &bufs, iovs, iovs_len); if (err != UVWASI_ESUCCESS) { uv_mutex_unlock(&wrap->mutex); @@ -1634,13 +1657,21 @@ uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi, iovs_len, nwritten); - if (uvwasi == NULL || iovs == NULL || nwritten == NULL) + if (uvwasi == NULL || (iovs == NULL && iovs_len > 0) || nwritten == NULL) return UVWASI_EINVAL; err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, UVWASI_RIGHT_FD_WRITE, 0); if (err != UVWASI_ESUCCESS) return err; + // libuv returns EINVAL in this case. To behave consistently with other + // Wasm runtimes, return OK here with a no-op. + if (iovs_len == 0) { + uv_mutex_unlock(&wrap->mutex); + *nwritten = 0; + return UVWASI_ESUCCESS; + } + err = uvwasi__setup_ciovs(uvwasi, &bufs, iovs, iovs_len); if (err != UVWASI_ESUCCESS) { uv_mutex_unlock(&wrap->mutex); @@ -2168,7 +2199,7 @@ uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi, memcpy(buf, req.ptr, len); buf[len] = '\0'; - *bufused = len + 1; + *bufused = len; uv_fs_req_cleanup(&req); return UVWASI_ESUCCESS; } diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn index 68d92c3477bc2c..c42d5b8624b2ae 100644 --- a/deps/v8/BUILD.gn +++ b/deps/v8/BUILD.gn @@ -1585,6 +1585,28 @@ config("toolchain") { # of `this` in capture-by-value lambdas and preventing a build roll which # enables C++20 (see https://crbug.com/1374227). "-Wno-deprecated", + + # Fix build with older versions of GCC + # Ported from v8 bazel: https://crrev.com/c/3368869 + "-Wno-stringop-overflow", + + # Fix a number of bogus errors with gcc12 + # TODO(miladfarca): re-evaluate for future gcc upgrades + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111499 + "-Wno-stringop-overread", + + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104336 + "-Wno-restrict", + + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105523 + "-Wno-array-bounds", + + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108517 + "-Wno-nonnull", + + # Disable dangling pointer warnings, which are often false positives when + # using scopes. + "-Wno-dangling-pointer", ] } diff --git a/deps/v8/src/compiler/turboshaft/assembler.h b/deps/v8/src/compiler/turboshaft/assembler.h index 1859a24651b715..6a6e1968b8bbab 100644 --- a/deps/v8/src/compiler/turboshaft/assembler.h +++ b/deps/v8/src/compiler/turboshaft/assembler.h @@ -6,6 +6,7 @@ #define V8_COMPILER_TURBOSHAFT_ASSEMBLER_H_ #include +#include #include #include #include diff --git a/deps/v8/src/d8/d8.cc b/deps/v8/src/d8/d8.cc index 6a31685e467728..4c819794a26592 100644 --- a/deps/v8/src/d8/d8.cc +++ b/deps/v8/src/d8/d8.cc @@ -3916,7 +3916,9 @@ V8_NOINLINE void FuzzerMonitor::UseAfterFree() { // Use-after-free caught by ASAN. std::vector* storage = new std::vector(3); delete storage; +#if defined(__clang__) USE(storage->at(1)); +#endif } V8_NOINLINE void FuzzerMonitor::UseOfUninitializedValue() { diff --git a/deps/v8/src/wasm/function-compiler.cc b/deps/v8/src/wasm/function-compiler.cc index 4972776fd97736..d9c03c9ec7d005 100644 --- a/deps/v8/src/wasm/function-compiler.cc +++ b/deps/v8/src/wasm/function-compiler.cc @@ -110,7 +110,7 @@ WasmCompilationResult WasmCompilationUnit::ExecuteFunctionCompilation( case ExecutionTier::kNone: UNREACHABLE(); - case ExecutionTier::kLiftoff: + case ExecutionTier::kLiftoff: { // The --wasm-tier-mask-for-testing flag can force functions to be // compiled with TurboFan, and the --wasm-debug-mask-for-testing can force // them to be compiled for debugging, see documentation. @@ -147,8 +147,8 @@ WasmCompilationResult WasmCompilationUnit::ExecuteFunctionCompilation( // TODO(wasm): We could actually stop or remove the tiering unit for this // function to avoid compiling it twice with TurboFan. V8_FALLTHROUGH; - - case ExecutionTier::kTurbofan: + } + case ExecutionTier::kTurbofan: { compiler::WasmCompilationData data(func_body); data.func_index = func_index_; data.wire_bytes_storage = wire_bytes_storage; @@ -157,6 +157,9 @@ WasmCompilationResult WasmCompilationUnit::ExecuteFunctionCompilation( detected); result.for_debugging = for_debugging_; break; + } + default: + UNREACHABLE(); } DCHECK(result.succeeded()); diff --git a/deps/v8/src/wasm/wasm-disassembler.cc b/deps/v8/src/wasm/wasm-disassembler.cc index f12af425f45b17..6dc3e0ee012167 100644 --- a/deps/v8/src/wasm/wasm-disassembler.cc +++ b/deps/v8/src/wasm/wasm-disassembler.cc @@ -4,6 +4,8 @@ #include "src/wasm/wasm-disassembler.h" +#include + #include "src/debug/debug-interface.h" #include "src/numbers/conversions.h" #include "src/wasm/module-decoder-impl.h" diff --git a/deps/v8/third_party/inspector_protocol/crdtp/dispatch_test.cc b/deps/v8/third_party/inspector_protocol/crdtp/dispatch_test.cc index faef35503bea18..504ff2548de5c2 100644 --- a/deps/v8/third_party/inspector_protocol/crdtp/dispatch_test.cc +++ b/deps/v8/third_party/inspector_protocol/crdtp/dispatch_test.cc @@ -169,10 +169,11 @@ TEST(DispatchableTest, MessageWithUnknownProperty) { } TEST(DispatchableTest, DuplicateMapKey) { - for (const std::string& json : - {"{\"id\":42,\"id\":42}", "{\"params\":null,\"params\":null}", - "{\"method\":\"foo\",\"method\":\"foo\"}", - "{\"sessionId\":\"42\",\"sessionId\":\"42\"}"}) { + const std::array jsons = { + {"{\"id\":42,\"id\":42}", "{\"params\":null,\"params\":null}", + "{\"method\":\"foo\",\"method\":\"foo\"}", + "{\"sessionId\":\"42\",\"sessionId\":\"42\"}"}}; + for (const std::string& json : jsons) { SCOPED_TRACE("json = " + json); std::vector cbor; ASSERT_TRUE(json::ConvertJSONToCBOR(SpanFrom(json), &cbor).ok()); @@ -185,11 +186,12 @@ TEST(DispatchableTest, DuplicateMapKey) { } TEST(DispatchableTest, ValidMessageParsesOK_NoParams) { - for (const std::string& json : - {"{\"id\":42,\"method\":\"Foo.executeBar\",\"sessionId\":" - "\"f421ssvaz4\"}", - "{\"id\":42,\"method\":\"Foo.executeBar\",\"sessionId\":\"f421ssvaz4\"," - "\"params\":null}"}) { + const std::array jsons = { + {"{\"id\":42,\"method\":\"Foo.executeBar\",\"sessionId\":" + "\"f421ssvaz4\"}", + "{\"id\":42,\"method\":\"Foo.executeBar\",\"sessionId\":\"f421ssvaz4\"," + "\"params\":null}"}}; + for (const std::string& json : jsons) { SCOPED_TRACE("json = " + json); std::vector cbor; ASSERT_TRUE(json::ConvertJSONToCBOR(SpanFrom(json), &cbor).ok()); diff --git a/deps/v8/third_party/inspector_protocol/crdtp/json_test.cc b/deps/v8/third_party/inspector_protocol/crdtp/json_test.cc index 7e25888faeb1f0..739eefcc73f882 100644 --- a/deps/v8/third_party/inspector_protocol/crdtp/json_test.cc +++ b/deps/v8/third_party/inspector_protocol/crdtp/json_test.cc @@ -704,15 +704,16 @@ using ContainerTestTypes = ::testing::Types, std::string>; TYPED_TEST_SUITE(ConvertJSONToCBORTest, ContainerTestTypes); TYPED_TEST(ConvertJSONToCBORTest, RoundTripValidJson) { - for (const std::string& json_in : { - "{\"msg\":\"Hello, world.\",\"lst\":[1,2,3]}", - "3.1415", - "false", - "true", - "\"Hello, world.\"", - "[1,2,3]", - "[]", - }) { + const std::array jsons = {{ + "{\"msg\":\"Hello, world.\",\"lst\":[1,2,3]}", + "3.1415", + "false", + "true", + "\"Hello, world.\"", + "[1,2,3]", + "[]", + }}; + for (const std::string& json_in : jsons) { SCOPED_TRACE(json_in); TypeParam json(json_in.begin(), json_in.end()); std::vector cbor; diff --git a/doc/api/cli.md b/doc/api/cli.md index 53b13748dafec3..583282237a31ba 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1839,6 +1839,15 @@ added: v20.10.0 The maximum number of test files that the test runner CLI will execute concurrently. The default value is `os.availableParallelism() - 1`. +### `--test-force-exit` + + + +Configures the test runner to exit the process once all known tests have +finished executing even if the event loop would otherwise remain active. + ### `--test-name-pattern` @@ -1165,6 +1170,9 @@ changes: **Default:** `false`. * `files`: {Array} An array containing the list of files to run. **Default** matching files from [test runner execution model][]. + * `forceExit`: {boolean} Configures the test runner to exit the process once + all known tests have finished executing even if the event loop would + otherwise remain active. **Default:** `false`. * `inspectPort` {number|Function} Sets inspector port of test child process. This can be a number, or a function that takes no arguments and returns a number. If a nullish value is provided, each process gets its own port, diff --git a/doc/api/webstreams.md b/doc/api/webstreams.md index 400efce91bb0a7..034d1c5579389f 100644 --- a/doc/api/webstreams.md +++ b/doc/api/webstreams.md @@ -1029,7 +1029,7 @@ changes: description: This class is now exposed on the global object. --> -The `WritableStreamDefaultController` manage's the {WritableStream}'s +The `WritableStreamDefaultController` manages the {WritableStream}'s internal state. #### `writableStreamDefaultController.error([error])` diff --git a/doc/changelogs/CHANGELOG_V20.md b/doc/changelogs/CHANGELOG_V20.md index 4790938a51a940..781446ffe5ebfd 100644 --- a/doc/changelogs/CHANGELOG_V20.md +++ b/doc/changelogs/CHANGELOG_V20.md @@ -9,6 +9,7 @@ +20.14.0
    20.13.1
    20.13.0
    20.12.2
    @@ -59,6 +60,60 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + + +## 2024-05-28, Version 20.14.0 'Iron' (LTS), @marco-ippolito + +### Notable Changes + +* \[[`28d2baa17c`](https://github.com/nodejs/node/commit/28d2baa17c)] - **src,permission**: throw async errors on async APIs (Rafael Gonzaga) [#52730](https://github.com/nodejs/node/pull/52730) +* \[[`77e2bf029a`](https://github.com/nodejs/node/commit/77e2bf029a)] - **(SEMVER-MINOR)** **test\_runner**: support forced exit (Colin Ihrig) [#52038](https://github.com/nodejs/node/pull/52038) + +### Commits + +* \[[`e3ad05d8b0`](https://github.com/nodejs/node/commit/e3ad05d8b0)] - **deps**: V8: cherry-pick 500de8bd371b (Richard Lau) [#52676](https://github.com/nodejs/node/pull/52676) +* \[[`053282e661`](https://github.com/nodejs/node/commit/053282e661)] - **deps**: V8: backport c4be0a97f981 (Richard Lau) [#52183](https://github.com/nodejs/node/pull/52183) +* \[[`200dadb879`](https://github.com/nodejs/node/commit/200dadb879)] - **deps**: V8: cherry-pick f8d5e576b814 (Richard Lau) [#52183](https://github.com/nodejs/node/pull/52183) +* \[[`f5cd125e02`](https://github.com/nodejs/node/commit/f5cd125e02)] - **deps**: update googletest to fa6de7f (Node.js GitHub Bot) [#52949](https://github.com/nodejs/node/pull/52949) +* \[[`bbbfd7f4e1`](https://github.com/nodejs/node/commit/bbbfd7f4e1)] - **deps**: update corepack to 0.28.1 (Node.js GitHub Bot) [#52946](https://github.com/nodejs/node/pull/52946) +* \[[`7ba30a57a6`](https://github.com/nodejs/node/commit/7ba30a57a6)] - **deps**: update simdutf to 5.2.8 (Node.js GitHub Bot) [#52727](https://github.com/nodejs/node/pull/52727) +* \[[`b21a480a28`](https://github.com/nodejs/node/commit/b21a480a28)] - **deps**: update simdutf to 5.2.6 (Node.js GitHub Bot) [#52727](https://github.com/nodejs/node/pull/52727) +* \[[`6cfad60d97`](https://github.com/nodejs/node/commit/6cfad60d97)] - **deps**: update googletest to 2d16ed0 (Node.js GitHub Bot) [#51657](https://github.com/nodejs/node/pull/51657) +* \[[`34708d1429`](https://github.com/nodejs/node/commit/34708d1429)] - **deps**: update googletest to d83fee1 (Node.js GitHub Bot) [#51657](https://github.com/nodejs/node/pull/51657) +* \[[`c1d3e558e8`](https://github.com/nodejs/node/commit/c1d3e558e8)] - **deps**: update googletest to 5a37b51 (Node.js GitHub Bot) [#51657](https://github.com/nodejs/node/pull/51657) +* \[[`69959d0fca`](https://github.com/nodejs/node/commit/69959d0fca)] - **deps**: update googletest to 5197b1a (Node.js GitHub Bot) [#51657](https://github.com/nodejs/node/pull/51657) +* \[[`c8305f6057`](https://github.com/nodejs/node/commit/c8305f6057)] - **deps**: update googletest to eff443c (Node.js GitHub Bot) [#51657](https://github.com/nodejs/node/pull/51657) +* \[[`760b788704`](https://github.com/nodejs/node/commit/760b788704)] - **deps**: update googletest to c231e6f (Node.js GitHub Bot) [#51657](https://github.com/nodejs/node/pull/51657) +* \[[`301541cc8f`](https://github.com/nodejs/node/commit/301541cc8f)] - **deps**: update googletest to e4fdb87 (Node.js GitHub Bot) [#51657](https://github.com/nodejs/node/pull/51657) +* \[[`981d57e401`](https://github.com/nodejs/node/commit/981d57e401)] - **deps**: update googletest to 5df0241 (Node.js GitHub Bot) [#51657](https://github.com/nodejs/node/pull/51657) +* \[[`a1817f534d`](https://github.com/nodejs/node/commit/a1817f534d)] - **deps**: update googletest to b75ecf1 (Node.js GitHub Bot) [#51657](https://github.com/nodejs/node/pull/51657) +* \[[`42070ca189`](https://github.com/nodejs/node/commit/42070ca189)] - **deps**: update googletest to 4565741 (Node.js GitHub Bot) [#51657](https://github.com/nodejs/node/pull/51657) +* \[[`edc3e5d056`](https://github.com/nodejs/node/commit/edc3e5d056)] - **deps**: update uvwasi to 0.0.21 (Node.js GitHub Bot) [#52863](https://github.com/nodejs/node/pull/52863) +* \[[`26b1231ffb`](https://github.com/nodejs/node/commit/26b1231ffb)] - **deps**: upgrade npm to 10.7.0 (npm team) [#52767](https://github.com/nodejs/node/pull/52767) +* \[[`e6d9fbece2`](https://github.com/nodejs/node/commit/e6d9fbece2)] - **doc**: update process.versions properties (ishabi) [#52736](https://github.com/nodejs/node/pull/52736) +* \[[`8c1f837c0a`](https://github.com/nodejs/node/commit/8c1f837c0a)] - **doc**: remove mold use on mac for speeding up build (Cong Zhang) [#52252](https://github.com/nodejs/node/pull/52252) +* \[[`d9c5114694`](https://github.com/nodejs/node/commit/d9c5114694)] - **doc**: fix grammatical mistake (codershiba) [#52808](https://github.com/nodejs/node/pull/52808) +* \[[`b350f435b7`](https://github.com/nodejs/node/commit/b350f435b7)] - **meta**: add mailmap entry for legendecas (Chengzhong Wu) [#52795](https://github.com/nodejs/node/pull/52795) +* \[[`61f9f12eff`](https://github.com/nodejs/node/commit/61f9f12eff)] - **meta**: bump actions/checkout from 4.1.1 to 4.1.4 (dependabot\[bot]) [#52787](https://github.com/nodejs/node/pull/52787) +* \[[`ac563667d6`](https://github.com/nodejs/node/commit/ac563667d6)] - **meta**: bump github/codeql-action from 3.24.9 to 3.25.3 (dependabot\[bot]) [#52786](https://github.com/nodejs/node/pull/52786) +* \[[`70611d7924`](https://github.com/nodejs/node/commit/70611d7924)] - **meta**: bump actions/upload-artifact from 4.3.1 to 4.3.3 (dependabot\[bot]) [#52785](https://github.com/nodejs/node/pull/52785) +* \[[`30482ea273`](https://github.com/nodejs/node/commit/30482ea273)] - **meta**: bump actions/download-artifact from 4.1.4 to 4.1.7 (dependabot\[bot]) [#52784](https://github.com/nodejs/node/pull/52784) +* \[[`d1607cdebb`](https://github.com/nodejs/node/commit/d1607cdebb)] - **meta**: bump codecov/codecov-action from 4.1.1 to 4.3.1 (dependabot\[bot]) [#52783](https://github.com/nodejs/node/pull/52783) +* \[[`21f1b6bfc3`](https://github.com/nodejs/node/commit/21f1b6bfc3)] - **meta**: bump step-security/harden-runner from 2.7.0 to 2.7.1 (dependabot\[bot]) [#52782](https://github.com/nodejs/node/pull/52782) +* \[[`0c6019a222`](https://github.com/nodejs/node/commit/0c6019a222)] - **meta**: standardize regex (Aviv Keller) [#52693](https://github.com/nodejs/node/pull/52693) +* \[[`28d2baa17c`](https://github.com/nodejs/node/commit/28d2baa17c)] - **src,permission**: throw async errors on async APIs (Rafael Gonzaga) [#52730](https://github.com/nodejs/node/pull/52730) +* \[[`cffd2cc0c9`](https://github.com/nodejs/node/commit/cffd2cc0c9)] - _**Revert**_ "**stream**: revert fix cloned webstreams not being unref'd" (Marco Ippolito) [#53144](https://github.com/nodejs/node/pull/53144) +* \[[`3dd96f1fab`](https://github.com/nodejs/node/commit/3dd96f1fab)] - **stream**: implement TransformStream cleanup using "transformer.cancel" (Debadree Chatterjee) [#50126](https://github.com/nodejs/node/pull/50126) +* \[[`8e7e778e01`](https://github.com/nodejs/node/commit/8e7e778e01)] - **test**: skip v8-updates/test-linux-perf (Michaël Zasso) [#49639](https://github.com/nodejs/node/pull/49639) +* \[[`f8e18869e9`](https://github.com/nodejs/node/commit/f8e18869e9)] - **test**: replace always-opt flag with alway-turbofan (Michaël Zasso) [#50115](https://github.com/nodejs/node/pull/50115) +* \[[`a501860d63`](https://github.com/nodejs/node/commit/a501860d63)] - **test\_runner**: don't await the same promise for each test (Colin Ihrig) [#52185](https://github.com/nodejs/node/pull/52185) +* \[[`e2ae4367f4`](https://github.com/nodejs/node/commit/e2ae4367f4)] - **test\_runner**: run top level tests in a microtask (Colin Ihrig) [#52092](https://github.com/nodejs/node/pull/52092) +* \[[`77e2bf029a`](https://github.com/nodejs/node/commit/77e2bf029a)] - **(SEMVER-MINOR)** **test\_runner**: support forced exit (Colin Ihrig) [#52038](https://github.com/nodejs/node/pull/52038) +* \[[`b7bc63565e`](https://github.com/nodejs/node/commit/b7bc63565e)] - **test\_runner**: ignore todo flag when running suites (Colin Ihrig) [#52117](https://github.com/nodejs/node/pull/52117) +* \[[`be587e3ae3`](https://github.com/nodejs/node/commit/be587e3ae3)] - **test\_runner**: use paths for test locations (Colin Ihrig) [#52010](https://github.com/nodejs/node/pull/52010) +* \[[`743281ab25`](https://github.com/nodejs/node/commit/743281ab25)] - **test\_runner**: support source mapped test locations (Colin Ihrig) [#52010](https://github.com/nodejs/node/pull/52010) +* \[[`4051316d95`](https://github.com/nodejs/node/commit/4051316d95)] - **tools**: update lint-md-dependencies to rollup\@4.17.0 (Node.js GitHub Bot) [#52729](https://github.com/nodejs/node/pull/52729) + ## 2024-05-09, Version 20.13.1 'Iron' (LTS), @marco-ippolito diff --git a/doc/node.1 b/doc/node.1 index 2966c14e1c3f5e..8dda6c13622171 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -425,6 +425,10 @@ Starts the Node.js command line test runner. The maximum number of test files that the test runner CLI will execute concurrently. . +.It Fl -test-force-exit +Configures the test runner to exit the process once all known tests have +finished executing even if the event loop would otherwise remain active. +. .It Fl -test-name-pattern A regular expression that configures the test runner to only execute tests whose name matches the provided pattern. diff --git a/lib/internal/test_runner/harness.js b/lib/internal/test_runner/harness.js index 2ca796dec34252..3a00e5a3fcceab 100644 --- a/lib/internal/test_runner/harness.js +++ b/lib/internal/test_runner/harness.js @@ -26,6 +26,7 @@ const { setupTestReporters, shouldColorizeTestFiles, } = require('internal/test_runner/utils'); +const { queueMicrotask } = require('internal/process/task_queues'); const { bigint: hrtime } = process.hrtime; const testResources = new SafeMap(); @@ -189,6 +190,7 @@ function setup(root) { root.harness = { __proto__: null, + allowTestsToRun: false, bootstrapComplete: false, watching: false, coverage: FunctionPrototypeBind(collectCoverage, null, root, coverage), @@ -207,6 +209,7 @@ function setup(root) { }, counters: null, shouldColorizeTestFiles: false, + teardown: exitHandler, }; root.harness.resetCounters(); root.startTime = hrtime(); @@ -230,8 +233,21 @@ function getGlobalRoot() { } async function startSubtest(subtest) { - await reportersSetup; - getGlobalRoot().harness.bootstrapComplete = true; + if (reportersSetup) { + // Only incur the overhead of awaiting the Promise once. + await reportersSetup; + reportersSetup = undefined; + } + + const root = getGlobalRoot(); + if (!root.harness.bootstrapComplete) { + root.harness.bootstrapComplete = true; + queueMicrotask(() => { + root.harness.allowTestsToRun = true; + root.processPendingSubtests(); + }); + } + await subtest.start(); } diff --git a/lib/internal/test_runner/runner.js b/lib/internal/test_runner/runner.js index cbbea6084c5d4b..463729d67d1b75 100644 --- a/lib/internal/test_runner/runner.js +++ b/lib/internal/test_runner/runner.js @@ -156,8 +156,11 @@ function filterExecArgv(arg, i, arr) { !ArrayPrototypeSome(kFilterArgValues, (p) => arg === p || (i > 0 && arr[i - 1] === p) || StringPrototypeStartsWith(arg, `${p}=`)); } -function getRunArgs(path, { inspectPort, testNamePatterns, only }) { +function getRunArgs(path, { forceExit, inspectPort, testNamePatterns, only }) { const argv = ArrayPrototypeFilter(process.execArgv, filterExecArgv); + if (forceExit === true) { + ArrayPrototypePush(argv, '--test-force-exit'); + } if (isUsingInspector()) { ArrayPrototypePush(argv, `--inspect-port=${getInspectPort(inspectPort)}`); } @@ -490,7 +493,17 @@ function run(options) { options = kEmptyObject; } let { testNamePatterns, shard } = options; - const { concurrency, timeout, signal, files, inspectPort, watch, setup, only } = options; + const { + concurrency, + timeout, + signal, + files, + forceExit, + inspectPort, + watch, + setup, + only, + } = options; if (files != null) { validateArray(files, 'options.files'); @@ -498,6 +511,15 @@ function run(options) { if (watch != null) { validateBoolean(watch, 'options.watch'); } + if (forceExit != null) { + validateBoolean(forceExit, 'options.forceExit'); + + if (forceExit && watch) { + throw new ERR_INVALID_ARG_VALUE( + 'options.forceExit', watch, 'is not supported with watch mode', + ); + } + } if (only != null) { validateBoolean(only, 'options.only'); } @@ -553,13 +575,22 @@ function run(options) { let postRun = () => root.postRun(); let filesWatcher; - const opts = { __proto__: null, root, signal, inspectPort, testNamePatterns, only }; + const opts = { + __proto__: null, + root, + signal, + inspectPort, + testNamePatterns, + only, + forceExit, + }; if (watch) { filesWatcher = watchFiles(testFiles, opts); postRun = undefined; } const runFiles = () => { root.harness.bootstrapComplete = true; + root.harness.allowTestsToRun = true; return SafePromiseAllSettledReturnVoid(testFiles, (path) => { const subtest = runTestFile(path, filesWatcher, opts); filesWatcher?.runningSubtests.set(path, subtest); diff --git a/lib/internal/test_runner/test.js b/lib/internal/test_runner/test.js index a042e936475f87..9ce486a3054035 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -15,6 +15,7 @@ const { PromisePrototypeThen, PromiseResolve, SafePromisePrototypeFinally, + StringPrototypeStartsWith, ReflectApply, RegExpPrototypeExec, SafeMap, @@ -58,6 +59,7 @@ const { } = require('internal/validators'); const { setTimeout } = require('timers'); const { TIMEOUT_MAX } = require('internal/timers'); +const { fileURLToPath } = require('internal/url'); const { availableParallelism } = require('os'); const { bigint: hrtime } = process.hrtime; const kCallbackAndPromisePresent = 'callbackAndPromisePresent'; @@ -76,8 +78,22 @@ const kHookNames = ObjectSeal(['before', 'after', 'beforeEach', 'afterEach']); const kUnwrapErrors = new SafeSet() .add(kTestCodeFailure).add(kHookFailure) .add('uncaughtException').add('unhandledRejection'); -const { testNamePatterns, testOnlyFlag } = parseCommandLine(); +const { + forceExit, + sourceMaps, + testNamePatterns, + testOnlyFlag, +} = parseCommandLine(); let kResistStopPropagation; +let findSourceMap; + +function lazyFindSourceMap(file) { + if (findSourceMap === undefined) { + ({ findSourceMap } = require('internal/source_map/source_map_cache')); + } + + return findSourceMap(file); +} function stopTest(timeout, signal) { const deferred = createDeferredPromise(); @@ -365,6 +381,21 @@ class Test extends AsyncResource { column: loc[1], file: loc[2], }; + + if (sourceMaps === true) { + const map = lazyFindSourceMap(this.loc.file); + const entry = map?.findEntry(this.loc.line - 1, this.loc.column - 1); + + if (entry !== undefined) { + this.loc.line = entry.originalLine + 1; + this.loc.column = entry.originalColumn + 1; + this.loc.file = entry.originalSource; + } + } + + if (StringPrototypeStartsWith(this.loc.file, 'file://')) { + this.loc.file = fileURLToPath(this.loc.file); + } } } @@ -553,7 +584,7 @@ class Test extends AsyncResource { // it. Otherwise, return a Promise to the caller and mark the test as // pending for later execution. this.reporter.enqueue(this.nesting, this.loc, this.name); - if (!this.parent.hasConcurrency()) { + if (!this.root.harness.allowTestsToRun || !this.parent.hasConcurrency()) { const deferred = createDeferredPromise(); deferred.test = this; @@ -696,6 +727,16 @@ class Test extends AsyncResource { // This helps catch any asynchronous activity that occurs after the tests // have finished executing. this.postRun(); + } else if (forceExit) { + // This is the root test, and all known tests and hooks have finished + // executing. If the user wants to force exit the process regardless of + // any remaining ref'ed handles, then do that now. It is theoretically + // possible that a ref'ed handle could asynchronously create more tests, + // but the user opted into this behavior. + this.reporter.once('close', () => { + process.exit(); + }); + this.harness.teardown(); } } @@ -744,12 +785,11 @@ class Test extends AsyncResource { if (this.parent === this.root && this.root.activeSubtests === 0 && this.root.pendingSubtests.length === 0 && - this.root.readySubtests.size === 0 && - this.root.hooks.after.length > 0) { - // This is done so that any global after() hooks are run. At this point - // all of the tests have finished running. However, there might be - // ref'ed handles keeping the event loop alive. This gives the global - // after() hook a chance to clean them up. + this.root.readySubtests.size === 0) { + // At this point all of the tests have finished running. However, there + // might be ref'ed handles keeping the event loop alive. This gives the + // global after() hook a chance to clean them up. The user may also + // want to force the test runner to exit despite ref'ed handles. this.root.run(); } } else if (!this.reported) { @@ -926,7 +966,7 @@ class Suite extends Test { constructor(options) { super(options); - if (testNamePatterns !== null && !options.skip && !options.todo) { + if (testNamePatterns !== null && !options.skip) { this.fn = options.fn || this.fn; this.skipped = false; } diff --git a/lib/internal/test_runner/utils.js b/lib/internal/test_runner/utils.js index 339631f08fe945..6306ddfa0689d3 100644 --- a/lib/internal/test_runner/utils.js +++ b/lib/internal/test_runner/utils.js @@ -199,6 +199,8 @@ function parseCommandLine() { const isTestRunner = getOptionValue('--test'); const coverage = getOptionValue('--experimental-test-coverage'); + const forceExit = getOptionValue('--test-force-exit'); + const sourceMaps = getOptionValue('--enable-source-maps'); const isChildProcess = process.env.NODE_TEST_CONTEXT === 'child'; const isChildProcessV8 = process.env.NODE_TEST_CONTEXT === 'child-v8'; let destinations; @@ -250,6 +252,8 @@ function parseCommandLine() { __proto__: null, isTestRunner, coverage, + forceExit, + sourceMaps, testOnlyFlag, testNamePatterns, reporters, diff --git a/lib/internal/webstreams/readablestream.js b/lib/internal/webstreams/readablestream.js index 8365748bdea1fe..abd896abeaa980 100644 --- a/lib/internal/webstreams/readablestream.js +++ b/lib/internal/webstreams/readablestream.js @@ -14,6 +14,7 @@ const { ObjectCreate, ObjectDefineProperties, ObjectSetPrototypeOf, + Promise, PromisePrototypeThen, PromiseResolve, PromiseReject, @@ -2441,7 +2442,7 @@ function setupReadableStreamDefaultController( const startResult = startAlgorithm(); PromisePrototypeThen( - PromiseResolve(startResult), + new Promise((r) => r(startResult)), () => { controller[kState].started = true; assert(!controller[kState].pulling); @@ -3240,7 +3241,7 @@ function setupReadableByteStreamController( const startResult = startAlgorithm(); PromisePrototypeThen( - PromiseResolve(startResult), + new Promise((r) => r(startResult)), () => { controller[kState].started = true; assert(!controller[kState].pulling); diff --git a/lib/internal/webstreams/transfer.js b/lib/internal/webstreams/transfer.js index 4e5d94fa045f19..bc4526d13b7a3d 100644 --- a/lib/internal/webstreams/transfer.js +++ b/lib/internal/webstreams/transfer.js @@ -146,6 +146,8 @@ class CrossRealmTransformReadableSource { error); port.close(); }; + + port.unref(); } start(controller) { @@ -219,6 +221,7 @@ class CrossRealmTransformWritableSink { port.close(); }; + port.unref(); } start(controller) { diff --git a/lib/internal/webstreams/transformstream.js b/lib/internal/webstreams/transformstream.js index bcccf90af91a0f..5e780705311ac2 100644 --- a/lib/internal/webstreams/transformstream.js +++ b/lib/internal/webstreams/transformstream.js @@ -5,7 +5,6 @@ const { FunctionPrototypeCall, ObjectDefineProperties, PromisePrototypeThen, - PromiseResolve, ReflectConstruct, SymbolToStringTag, Symbol, @@ -47,6 +46,7 @@ const { nonOpFlush, kType, kState, + nonOpCancel, } = require('internal/webstreams/util'); const { @@ -377,8 +377,7 @@ function initializeTransformStream( return transformStreamDefaultSourcePullAlgorithm(stream); }, cancel(reason) { - transformStreamErrorWritableAndUnblockWrite(stream, reason); - return PromiseResolve(); + return transformStreamDefaultSourceCancelAlgorithm(stream, reason); }, }, { highWaterMark: readableHighWaterMark, @@ -420,6 +419,10 @@ function transformStreamErrorWritableAndUnblockWrite(stream, error) { writableStreamDefaultControllerErrorIfNeeded( writable[kState].controller, error); + transformStreamUnblockWrite(stream); +} + +function transformStreamUnblockWrite(stream) { if (stream[kState].backpressure) transformStreamSetBackpressure(stream, false); } @@ -436,13 +439,15 @@ function setupTransformStreamDefaultController( stream, controller, transformAlgorithm, - flushAlgorithm) { + flushAlgorithm, + cancelAlgorithm) { assert(isTransformStream(stream)); assert(stream[kState].controller === undefined); controller[kState] = { stream, transformAlgorithm, flushAlgorithm, + cancelAlgorithm, }; stream[kState].controller = controller; } @@ -453,21 +458,26 @@ function setupTransformStreamDefaultControllerFromTransformer( const controller = new TransformStreamDefaultController(kSkipThrow); const transform = transformer?.transform || defaultTransformAlgorithm; const flush = transformer?.flush || nonOpFlush; + const cancel = transformer?.cancel || nonOpCancel; const transformAlgorithm = FunctionPrototypeBind(transform, transformer); const flushAlgorithm = FunctionPrototypeBind(flush, transformer); + const cancelAlgorithm = + FunctionPrototypeBind(cancel, transformer); setupTransformStreamDefaultController( stream, controller, transformAlgorithm, - flushAlgorithm); + flushAlgorithm, + cancelAlgorithm); } function transformStreamDefaultControllerClearAlgorithms(controller) { controller[kState].transformAlgorithm = undefined; controller[kState].flushAlgorithm = undefined; + controller[kState].cancelAlgorithm = undefined; } function transformStreamDefaultControllerEnqueue(controller, chunk) { @@ -556,7 +566,40 @@ function transformStreamDefaultSinkWriteAlgorithm(stream, chunk) { } async function transformStreamDefaultSinkAbortAlgorithm(stream, reason) { - transformStreamError(stream, reason); + const { + controller, + readable, + } = stream[kState]; + + if (controller[kState].finishPromise !== undefined) { + return controller[kState].finishPromise; + } + + const { promise, resolve, reject } = createDeferredPromise(); + controller[kState].finishPromise = promise; + const cancelPromise = ensureIsPromise( + controller[kState].cancelAlgorithm, + controller, + reason); + transformStreamDefaultControllerClearAlgorithms(controller); + + PromisePrototypeThen( + cancelPromise, + () => { + if (readable[kState].state === 'errored') + reject(readable[kState].storedError); + else { + readableStreamDefaultControllerError(readable[kState].controller, reason); + resolve(); + } + }, + (error) => { + readableStreamDefaultControllerError(readable[kState].controller, error); + reject(error); + }, + ); + + return controller[kState].finishPromise; } function transformStreamDefaultSinkCloseAlgorithm(stream) { @@ -565,23 +608,32 @@ function transformStreamDefaultSinkCloseAlgorithm(stream) { controller, } = stream[kState]; + if (controller[kState].finishPromise !== undefined) { + return controller[kState].finishPromise; + } + const { promise, resolve, reject } = createDeferredPromise(); + controller[kState].finishPromise = promise; const flushPromise = ensureIsPromise( controller[kState].flushAlgorithm, controller, controller); transformStreamDefaultControllerClearAlgorithms(controller); - return PromisePrototypeThen( + PromisePrototypeThen( flushPromise, () => { if (readable[kState].state === 'errored') - throw readable[kState].storedError; - readableStreamDefaultControllerClose(readable[kState].controller); + reject(readable[kState].storedError); + else { + readableStreamDefaultControllerClose(readable[kState].controller); + resolve(); + } }, (error) => { - transformStreamError(stream, error); - throw readable[kState].storedError; + readableStreamDefaultControllerError(readable[kState].controller, error); + reject(error); }); + return controller[kState].finishPromise; } function transformStreamDefaultSourcePullAlgorithm(stream) { @@ -591,6 +643,48 @@ function transformStreamDefaultSourcePullAlgorithm(stream) { return stream[kState].backpressureChange.promise; } +function transformStreamDefaultSourceCancelAlgorithm(stream, reason) { + const { + controller, + writable, + } = stream[kState]; + + if (controller[kState].finishPromise !== undefined) { + return controller[kState].finishPromise; + } + + const { promise, resolve, reject } = createDeferredPromise(); + controller[kState].finishPromise = promise; + const cancelPromise = ensureIsPromise( + controller[kState].cancelAlgorithm, + controller, + reason); + transformStreamDefaultControllerClearAlgorithms(controller); + + PromisePrototypeThen(cancelPromise, + () => { + if (writable[kState].state === 'errored') + reject(writable[kState].storedError); + else { + writableStreamDefaultControllerErrorIfNeeded( + writable[kState].controller, + reason); + transformStreamUnblockWrite(stream); + resolve(); + } + }, + (error) => { + writableStreamDefaultControllerErrorIfNeeded( + writable[kState].controller, + error); + transformStreamUnblockWrite(stream); + reject(error); + }, + ); + + return controller[kState].finishPromise; +} + module.exports = { TransformStream, TransformStreamDefaultController, diff --git a/lib/internal/webstreams/writablestream.js b/lib/internal/webstreams/writablestream.js index 0f2b1dc0bdc787..0e807982ee7471 100644 --- a/lib/internal/webstreams/writablestream.js +++ b/lib/internal/webstreams/writablestream.js @@ -6,6 +6,7 @@ const { FunctionPrototypeBind, FunctionPrototypeCall, ObjectDefineProperties, + Promise, PromisePrototypeThen, PromiseResolve, PromiseReject, @@ -1290,7 +1291,7 @@ function setupWritableStreamDefaultController( const startResult = startAlgorithm(); PromisePrototypeThen( - PromiseResolve(startResult), + new Promise((r) => r(startResult)), () => { assert(stream[kState].state === 'writable' || stream[kState].state === 'erroring'); diff --git a/src/node_dir.cc b/src/node_dir.cc index 21d5b880ccee98..4c742856cd9092 100644 --- a/src/node_dir.cc +++ b/src/node_dir.cc @@ -367,19 +367,24 @@ static void OpenDir(const FunctionCallbackInfo& args) { BufferValue path(isolate, args[0]); CHECK_NOT_NULL(*path); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); const enum encoding encoding = ParseEncoding(isolate, args[1], UTF8); FSReqBase* req_wrap_async = GetReqWrap(args, 2); if (req_wrap_async != nullptr) { // openDir(path, encoding, req) + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemRead, + path.ToStringView()); FS_DIR_ASYNC_TRACE_BEGIN1( UV_FS_OPENDIR, req_wrap_async, "path", TRACE_STR_COPY(*path)) AsyncCall(env, req_wrap_async, args, "opendir", encoding, AfterOpenDir, uv_fs_opendir, *path); } else { // openDir(path, encoding, undefined, ctx) CHECK_EQ(argc, 4); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); FSReqWrapSync req_wrap_sync; FS_DIR_SYNC_TRACE_BEGIN(opendir); int result = SyncCall(env, args[3], &req_wrap_sync, "opendir", diff --git a/src/node_file.cc b/src/node_file.cc index 913fdf2d7826b7..0ec5c6f4845e7b 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -960,17 +960,22 @@ void Access(const FunctionCallbackInfo& args) { BufferValue path(isolate, args[0]); CHECK_NOT_NULL(*path); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); if (argc > 2) { // access(path, mode, req) FSReqBase* req_wrap_async = GetReqWrap(args, 2); CHECK_NOT_NULL(req_wrap_async); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemRead, + path.ToStringView()); FS_ASYNC_TRACE_BEGIN1( UV_FS_ACCESS, req_wrap_async, "path", TRACE_STR_COPY(*path)) AsyncCall(env, req_wrap_async, args, "access", UTF8, AfterNoArgs, uv_fs_access, *path, mode); } else { // access(path, mode) + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); FSReqWrapSync req_wrap_sync("access", *path); FS_SYNC_TRACE_BEGIN(access); SyncCallAndThrowOnError(env, &req_wrap_sync, uv_fs_access, *path, mode); @@ -1167,18 +1172,23 @@ static void Stat(const FunctionCallbackInfo& args) { BufferValue path(realm->isolate(), args[0]); CHECK_NOT_NULL(*path); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); bool use_bigint = args[1]->IsTrue(); if (!args[2]->IsUndefined()) { // stat(path, use_bigint, req) FSReqBase* req_wrap_async = GetReqWrap(args, 2, use_bigint); CHECK_NOT_NULL(req_wrap_async); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemRead, + path.ToStringView()); FS_ASYNC_TRACE_BEGIN1( UV_FS_STAT, req_wrap_async, "path", TRACE_STR_COPY(*path)) AsyncCall(env, req_wrap_async, args, "stat", UTF8, AfterStat, uv_fs_stat, *path); } else { // stat(path, use_bigint, undefined, do_not_throw_if_no_entry) + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); bool do_not_throw_if_no_entry = args[3]->IsFalse(); FSReqWrapSync req_wrap_sync("stat", *path); FS_SYNC_TRACE_BEGIN(stat); @@ -1288,13 +1298,16 @@ static void StatFs(const FunctionCallbackInfo& args) { BufferValue path(realm->isolate(), args[0]); CHECK_NOT_NULL(*path); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); bool use_bigint = args[1]->IsTrue(); if (argc > 2) { // statfs(path, use_bigint, req) FSReqBase* req_wrap_async = GetReqWrap(args, 2, use_bigint); CHECK_NOT_NULL(req_wrap_async); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemRead, + path.ToStringView()); FS_ASYNC_TRACE_BEGIN1( UV_FS_STATFS, req_wrap_async, "path", TRACE_STR_COPY(*path)) AsyncCall(env, @@ -1306,6 +1319,8 @@ static void StatFs(const FunctionCallbackInfo& args) { uv_fs_statfs, *path); } else { // statfs(path, use_bigint) + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); FSReqWrapSync req_wrap_sync("statfs", *path); FS_SYNC_TRACE_BEGIN(statfs); int result = @@ -1377,20 +1392,30 @@ static void Link(const FunctionCallbackInfo& args) { CHECK_NOT_NULL(*src); const auto src_view = src.ToStringView(); - // To avoid bypass the link target should be allowed to read and write - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemRead, src_view); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemWrite, src_view); BufferValue dest(isolate, args[1]); CHECK_NOT_NULL(*dest); const auto dest_view = dest.ToStringView(); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemWrite, dest_view); if (argc > 2) { // link(src, dest, req) FSReqBase* req_wrap_async = GetReqWrap(args, 2); + // To avoid bypass the link target should be allowed to read and write + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemRead, + src_view); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemWrite, + src_view); + + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemWrite, + dest_view); FS_ASYNC_TRACE_BEGIN2(UV_FS_LINK, req_wrap_async, "src", @@ -1400,6 +1425,14 @@ static void Link(const FunctionCallbackInfo& args) { AsyncDestCall(env, req_wrap_async, args, "link", *dest, dest.length(), UTF8, AfterNoArgs, uv_fs_link, *src, *dest); } else { // link(src, dest) + // To avoid bypass the link target should be allowed to read and write + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, src_view); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemWrite, src_view); + + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemWrite, dest_view); FSReqWrapSync req_wrap_sync("link", *src, *dest); FS_SYNC_TRACE_BEGIN(link); SyncCallAndThrowOnError(env, &req_wrap_sync, uv_fs_link, *src, *dest); @@ -1462,20 +1495,27 @@ static void Rename(const FunctionCallbackInfo& args) { BufferValue old_path(isolate, args[0]); CHECK_NOT_NULL(*old_path); auto view_old_path = old_path.ToStringView(); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemRead, view_old_path); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemWrite, view_old_path); BufferValue new_path(isolate, args[1]); CHECK_NOT_NULL(*new_path); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, - permission::PermissionScope::kFileSystemWrite, - new_path.ToStringView()); if (argc > 2) { // rename(old_path, new_path, req) FSReqBase* req_wrap_async = GetReqWrap(args, 2); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemRead, + view_old_path); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemWrite, + view_old_path); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemWrite, + new_path.ToStringView()); FS_ASYNC_TRACE_BEGIN2(UV_FS_RENAME, req_wrap_async, "old_path", @@ -1486,6 +1526,14 @@ static void Rename(const FunctionCallbackInfo& args) { new_path.length(), UTF8, AfterNoArgs, uv_fs_rename, *old_path, *new_path); } else { // rename(old_path, new_path) + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, view_old_path); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemWrite, view_old_path); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + permission::PermissionScope::kFileSystemWrite, + new_path.ToStringView()); FSReqWrapSync req_wrap_sync("rename", *old_path, *new_path); FS_SYNC_TRACE_BEGIN(rename); SyncCallAndThrowOnError( @@ -1579,17 +1627,24 @@ static void Unlink(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemWrite, path.ToStringView()); if (argc > 1) { // unlink(path, req) FSReqBase* req_wrap_async = GetReqWrap(args, 1); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemWrite, + path.ToStringView()); CHECK_NOT_NULL(req_wrap_async); FS_ASYNC_TRACE_BEGIN1( UV_FS_UNLINK, req_wrap_async, "path", TRACE_STR_COPY(*path)) AsyncCall(env, req_wrap_async, args, "unlink", UTF8, AfterNoArgs, uv_fs_unlink, *path); } else { // unlink(path) + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + permission::PermissionScope::kFileSystemWrite, + path.ToStringView()); FSReqWrapSync req_wrap_sync("unlink", *path); FS_SYNC_TRACE_BEGIN(unlink); SyncCallAndThrowOnError(env, &req_wrap_sync, uv_fs_unlink, *path); @@ -1893,8 +1948,6 @@ static void ReadDir(const FunctionCallbackInfo& args) { BufferValue path(isolate, args[0]); CHECK_NOT_NULL(*path); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); const enum encoding encoding = ParseEncoding(isolate, args[1], UTF8); @@ -1902,6 +1955,11 @@ static void ReadDir(const FunctionCallbackInfo& args) { if (argc > 3) { // readdir(path, encoding, withTypes, req) FSReqBase* req_wrap_async = GetReqWrap(args, 3); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemRead, + path.ToStringView()); req_wrap_async->set_with_file_types(with_types); FS_ASYNC_TRACE_BEGIN1( UV_FS_SCANDIR, req_wrap_async, "path", TRACE_STR_COPY(*path)) @@ -1915,6 +1973,8 @@ static void ReadDir(const FunctionCallbackInfo& args) { *path, 0 /*flags*/); } else { // readdir(path, encoding, withTypes) + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); FSReqWrapSync req_wrap_sync("scandir", *path); FS_SYNC_TRACE_BEGIN(readdir); int err = SyncCallAndThrowOnError( @@ -1971,6 +2031,39 @@ static void ReadDir(const FunctionCallbackInfo& args) { } } +static inline Maybe AsyncCheckOpenPermissions(Environment* env, + FSReqBase* req_wrap, + const BufferValue& path, + int flags) { + // These flags capture the intention of the open() call. + const int rwflags = flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR); + + // These flags have write-like side effects even with O_RDONLY, at least on + // some operating systems. On Windows, for example, O_RDONLY | O_TEMPORARY + // can be used to delete a file. Bizarre. + const int write_as_side_effect = flags & (UV_FS_O_APPEND | UV_FS_O_CREAT | + UV_FS_O_TRUNC | UV_FS_O_TEMPORARY); + + auto pathView = path.ToStringView(); + if (rwflags != UV_FS_O_WRONLY) { + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap, + permission::PermissionScope::kFileSystemRead, + pathView, + Nothing()); + } + if (rwflags != UV_FS_O_RDONLY || write_as_side_effect) { + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap, + permission::PermissionScope::kFileSystemWrite, + pathView, + Nothing()); + } + return JustVoid(); +} + static inline Maybe CheckOpenPermissions(Environment* env, const BufferValue& path, int flags) { @@ -2016,17 +2109,18 @@ static void Open(const FunctionCallbackInfo& args) { CHECK(args[2]->IsInt32()); const int mode = args[2].As()->Value(); - if (CheckOpenPermissions(env, path, flags).IsNothing()) return; - if (argc > 3) { // open(path, flags, mode, req) FSReqBase* req_wrap_async = GetReqWrap(args, 3); CHECK_NOT_NULL(req_wrap_async); + if (AsyncCheckOpenPermissions(env, req_wrap_async, path, flags).IsNothing()) + return; req_wrap_async->set_is_plain_open(true); FS_ASYNC_TRACE_BEGIN1( UV_FS_OPEN, req_wrap_async, "path", TRACE_STR_COPY(*path)) AsyncCall(env, req_wrap_async, args, "open", UTF8, AfterInteger, uv_fs_open, *path, flags, mode); } else { // open(path, flags, mode) + if (CheckOpenPermissions(env, path, flags).IsNothing()) return; FSReqWrapSync req_wrap_sync("open", *path); FS_SYNC_TRACE_BEGIN(open); int result = SyncCallAndThrowOnError( @@ -2093,16 +2187,22 @@ static void CopyFile(const FunctionCallbackInfo& args) { BufferValue src(isolate, args[0]); CHECK_NOT_NULL(*src); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemRead, src.ToStringView()); BufferValue dest(isolate, args[1]); CHECK_NOT_NULL(*dest); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemWrite, dest.ToStringView()); if (argc > 3) { // copyFile(src, dest, flags, req) FSReqBase* req_wrap_async = GetReqWrap(args, 3); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemRead, + src.ToStringView()); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemWrite, + dest.ToStringView()); FS_ASYNC_TRACE_BEGIN2(UV_FS_COPYFILE, req_wrap_async, "src", @@ -2113,6 +2213,12 @@ static void CopyFile(const FunctionCallbackInfo& args) { *dest, dest.length(), UTF8, AfterNoArgs, uv_fs_copyfile, *src, *dest, flags); } else { // copyFile(src, dest, flags) + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, src.ToStringView()); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + permission::PermissionScope::kFileSystemWrite, + dest.ToStringView()); FSReqWrapSync req_wrap_sync("copyfile", *src, *dest); FS_SYNC_TRACE_BEGIN(copyfile); SyncCallAndThrowOnError( @@ -2662,8 +2768,6 @@ static void Chown(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemWrite, path.ToStringView()); CHECK(IsSafeJsInt(args[1])); const uv_uid_t uid = static_cast(args[1].As()->Value()); @@ -2673,11 +2777,21 @@ static void Chown(const FunctionCallbackInfo& args) { if (argc > 3) { // chown(path, uid, gid, req) FSReqBase* req_wrap_async = GetReqWrap(args, 3); + CHECK_NOT_NULL(req_wrap_async); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemWrite, + path.ToStringView()); FS_ASYNC_TRACE_BEGIN1( UV_FS_CHOWN, req_wrap_async, "path", TRACE_STR_COPY(*path)) AsyncCall(env, req_wrap_async, args, "chown", UTF8, AfterNoArgs, uv_fs_chown, *path, uid, gid); } else { // chown(path, uid, gid) + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + permission::PermissionScope::kFileSystemWrite, + path.ToStringView()); FSReqWrapSync req_wrap_sync("chown", *path); FS_SYNC_TRACE_BEGIN(chown); SyncCallAndThrowOnError(env, &req_wrap_sync, uv_fs_chown, *path, uid, gid); @@ -2728,8 +2842,6 @@ static void LChown(const FunctionCallbackInfo& args) { BufferValue path(env->isolate(), args[0]); CHECK_NOT_NULL(*path); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemWrite, path.ToStringView()); CHECK(IsSafeJsInt(args[1])); const uv_uid_t uid = static_cast(args[1].As()->Value()); @@ -2739,11 +2851,20 @@ static void LChown(const FunctionCallbackInfo& args) { if (argc > 3) { // lchown(path, uid, gid, req) FSReqBase* req_wrap_async = GetReqWrap(args, 3); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemWrite, + path.ToStringView()); FS_ASYNC_TRACE_BEGIN1( UV_FS_LCHOWN, req_wrap_async, "path", TRACE_STR_COPY(*path)) AsyncCall(env, req_wrap_async, args, "lchown", UTF8, AfterNoArgs, uv_fs_lchown, *path, uid, gid); } else { // lchown(path, uid, gid) + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + permission::PermissionScope::kFileSystemWrite, + path.ToStringView()); FSReqWrapSync req_wrap_sync("lchown", *path); FS_SYNC_TRACE_BEGIN(lchown); SyncCallAndThrowOnError(env, &req_wrap_sync, uv_fs_lchown, *path, uid, gid); @@ -2861,18 +2982,25 @@ static void Mkdtemp(const FunctionCallbackInfo& args) { snprintf(tmpl.out() + length, tmpl.length(), "%s", suffix); CHECK_NOT_NULL(*tmpl); - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemWrite, tmpl.ToStringView()); const enum encoding encoding = ParseEncoding(isolate, args[1], UTF8); if (argc > 2) { // mkdtemp(tmpl, encoding, req) FSReqBase* req_wrap_async = GetReqWrap(args, 2); + ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + req_wrap_async, + permission::PermissionScope::kFileSystemWrite, + tmpl.ToStringView()); FS_ASYNC_TRACE_BEGIN1( UV_FS_MKDTEMP, req_wrap_async, "path", TRACE_STR_COPY(*tmpl)) AsyncCall(env, req_wrap_async, args, "mkdtemp", encoding, AfterStringPath, uv_fs_mkdtemp, *tmpl); } else { // mkdtemp(tmpl, encoding) + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, + permission::PermissionScope::kFileSystemWrite, + tmpl.ToStringView()); FSReqWrapSync req_wrap_sync("mkdtemp", *tmpl); FS_SYNC_TRACE_BEGIN(mkdtemp); int result = diff --git a/src/node_options.cc b/src/node_options.cc index 556b3c1592e056..937ce44696175d 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -179,6 +179,9 @@ void EnvironmentOptions::CheckOptions(std::vector* errors, } else if (force_repl) { errors->push_back("either --watch or --interactive " "can be used, not both"); + } else if (test_runner_force_exit) { + errors->push_back("either --watch or --test-force-exit " + "can be used, not both"); } else if (!test_runner && (argv->size() < 1 || (*argv)[1].empty())) { errors->push_back("--watch requires specifying a file"); } @@ -617,6 +620,9 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { AddOption("--test-concurrency", "specify test runner concurrency", &EnvironmentOptions::test_runner_concurrency); + AddOption("--test-force-exit", + "force test runner to exit upon completion", + &EnvironmentOptions::test_runner_force_exit); AddOption("--test-timeout", "specify test runner timeout", &EnvironmentOptions::test_runner_timeout); diff --git a/src/node_options.h b/src/node_options.h index 703e1d2b1bfc55..0a2f5512f689f8 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -166,6 +166,7 @@ class EnvironmentOptions : public Options { uint64_t test_runner_concurrency = 0; uint64_t test_runner_timeout = 0; bool test_runner_coverage = false; + bool test_runner_force_exit = false; std::vector test_name_pattern; std::vector test_reporter; std::vector test_reporter_destination; diff --git a/src/node_version.h b/src/node_version.h index a94dfaac978c3a..b703723a1878fc 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -23,13 +23,13 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 20 -#define NODE_MINOR_VERSION 13 -#define NODE_PATCH_VERSION 2 +#define NODE_MINOR_VERSION 14 +#define NODE_PATCH_VERSION 0 #define NODE_VERSION_IS_LTS 1 #define NODE_VERSION_LTS_CODENAME "Iron" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) diff --git a/src/permission/permission.cc b/src/permission/permission.cc index 84235ed1b57731..50c21734400481 100644 --- a/src/permission/permission.cc +++ b/src/permission/permission.cc @@ -5,6 +5,7 @@ #include "node.h" #include "node_errors.h" #include "node_external_reference.h" +#include "node_file.h" #include "v8.h" @@ -99,16 +100,16 @@ Permission::Permission() : enabled_(false) { #undef V } -void Permission::ThrowAccessDenied(Environment* env, - PermissionScope perm, - const std::string_view& res) { +Local CreateAccessDeniedError(Environment* env, + PermissionScope perm, + const std::string_view& res) { Local err = ERR_ACCESS_DENIED(env->isolate()); CHECK(err->IsObject()); if (err.As() ->Set(env->context(), env->permission_string(), v8::String::NewFromUtf8(env->isolate(), - PermissionToString(perm), + Permission::PermissionToString(perm), v8::NewStringType::kNormal) .ToLocalChecked()) .IsNothing() || @@ -120,10 +121,27 @@ void Permission::ThrowAccessDenied(Environment* env, v8::NewStringType::kNormal) .ToLocalChecked()) .IsNothing()) - return; + return Local(); + return err; +} + +void Permission::ThrowAccessDenied(Environment* env, + PermissionScope perm, + const std::string_view& res) { + Local err = CreateAccessDeniedError(env, perm, res); + if (err.IsEmpty()) return; env->isolate()->ThrowException(err); } +void Permission::AsyncThrowAccessDenied(Environment* env, + fs::FSReqBase* req_wrap, + PermissionScope perm, + const std::string_view& res) { + Local err = CreateAccessDeniedError(env, perm, res); + if (err.IsEmpty()) return; + return req_wrap->Reject(err); +} + void Permission::EnablePermissions() { if (!enabled_) { enabled_ = true; diff --git a/src/permission/permission.h b/src/permission/permission.h index 3d37169eaaa17e..65c0ada72b63e0 100644 --- a/src/permission/permission.h +++ b/src/permission/permission.h @@ -19,6 +19,10 @@ namespace node { class Environment; +namespace fs { +class FSReqBase; +} + namespace permission { #define THROW_IF_INSUFFICIENT_PERMISSIONS(env, perm_, resource_, ...) \ @@ -30,6 +34,16 @@ namespace permission { } \ } while (0) +#define ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( \ + env, wrap, perm_, resource_, ...) \ + do { \ + if (UNLIKELY(!(env)->permission()->is_granted(perm_, resource_))) { \ + node::permission::Permission::AsyncThrowAccessDenied( \ + (env), wrap, perm_, resource_); \ + return __VA_ARGS__; \ + } \ + } while (0) + class Permission { public: Permission(); @@ -47,6 +61,10 @@ class Permission { static void ThrowAccessDenied(Environment* env, PermissionScope perm, const std::string_view& res); + static void AsyncThrowAccessDenied(Environment* env, + fs::FSReqBase* req_wrap, + PermissionScope perm, + const std::string_view& res); // CLI Call void Apply(Environment* env, diff --git a/test/fixtures/permission/fs-read.js b/test/fixtures/permission/fs-read.js index aa210243292ed0..43e1718ab15e2b 100644 --- a/test/fixtures/permission/fs-read.js +++ b/test/fixtures/permission/fs-read.js @@ -14,15 +14,20 @@ const regularFile = __filename; // fs.readFile { + fs.readFile(blockedFile, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.toNamespacedPath(blockedFile), + })); assert.throws(() => { - fs.readFile(blockedFile, () => {}); + fs.readFileSync(blockedFile); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { - fs.readFile(blockedFileURL, () => {}); + fs.readFileSync(blockedFileURL); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', @@ -67,23 +72,26 @@ const regularFile = __filename; // fs.stat { - assert.throws(() => { - fs.stat(blockedFile, () => {}); - }, common.expectsError({ + fs.stat(blockedFile, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { - fs.stat(blockedFileURL, () => {}); + fs.statSync(blockedFile); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { - fs.stat(path.join(blockedFolder, 'anyfile'), () => {}); + fs.statSync(blockedFileURL); }, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.toNamespacedPath(blockedFile), + })); + fs.stat(path.join(blockedFolder, 'anyfile'), common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(path.join(blockedFolder, 'anyfile')), @@ -97,22 +105,20 @@ const regularFile = __filename; // fs.access { - assert.throws(() => { - fs.access(blockedFile, fs.constants.R_OK, () => {}); - }, common.expectsError({ + fs.access(blockedFile, fs.constants.R_OK, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { - fs.access(blockedFileURL, fs.constants.R_OK, () => {}); + fs.accessSync(blockedFileURL, fs.constants.R_OK); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { - fs.access(path.join(blockedFolder, 'anyfile'), fs.constants.R_OK, () => {}); + fs.accessSync(path.join(blockedFolder, 'anyfile'), fs.constants.R_OK); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', @@ -127,22 +133,20 @@ const regularFile = __filename; // fs.copyFile { - assert.throws(() => { - fs.copyFile(blockedFile, path.join(blockedFolder, 'any-other-file'), () => {}); - }, common.expectsError({ + fs.copyFile(blockedFile, path.join(blockedFolder, 'any-other-file'), common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { - fs.copyFile(blockedFileURL, path.join(blockedFolder, 'any-other-file'), () => {}); + fs.copyFileSync(blockedFileURL, path.join(blockedFolder, 'any-other-file')); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { - fs.copyFile(blockedFile, path.join(__dirname, 'any-other-file'), () => {}); + fs.copyFileSync(blockedFile, path.join(__dirname, 'any-other-file')); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', @@ -179,22 +183,20 @@ const regularFile = __filename; // fs.open { - assert.throws(() => { - fs.open(blockedFile, 'r', () => {}); - }, common.expectsError({ + fs.open(blockedFile, 'r', common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { - fs.open(blockedFileURL, 'r', () => {}); + fs.openSync(blockedFileURL, 'r'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { - fs.open(path.join(blockedFolder, 'anyfile'), 'r', () => {}); + fs.openSync(path.join(blockedFolder, 'anyfile'), 'r'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', @@ -214,20 +216,21 @@ const regularFile = __filename; code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', }); - assert.throws(() => { - fs.open(blockedFile, fs.constants.O_RDWR | 0x10000000, common.mustNotCall()); - }, { + fs.open(blockedFile, fs.constants.O_RDWR | 0x10000000, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', - }); + })); } // fs.opendir { + fs.opendir(blockedFolder, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.toNamespacedPath(blockedFolder), + })); assert.throws(() => { - fs.opendir(blockedFolder, (err) => { - assert.ifError(err); - }); + fs.opendirSync(blockedFolder); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', @@ -242,8 +245,13 @@ const regularFile = __filename; // fs.readdir { + fs.readdir(blockedFolder, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.toNamespacedPath(blockedFolder), + })); assert.throws(() => { - fs.readdir(blockedFolder, () => {}); + fs.readdirSync(blockedFolder); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', @@ -299,15 +307,20 @@ const regularFile = __filename; // fs.rename { + fs.rename(blockedFile, 'newfile', common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.toNamespacedPath(blockedFile), + })); assert.throws(() => { - fs.rename(blockedFile, 'newfile', () => {}); + fs.renameSync(blockedFile, 'newfile'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { - fs.rename(blockedFileURL, 'newfile', () => {}); + fs.renameSync(blockedFileURL, 'newfile'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', @@ -342,22 +355,34 @@ const regularFile = __filename; fs.exists(blockedFileURL, (exists) => { assert.equal(exists, false); }); + assert.throws(() => { + fs.existsSync(blockedFile); + }, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.toNamespacedPath(blockedFile), + })); } // fs.statfs { + fs.statfs(blockedFile, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemRead', + resource: path.toNamespacedPath(blockedFile), + })); assert.throws(() => { - fs.statfs(blockedFile, () => {}); + fs.statfsSync(blockedFile); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(blockedFile), })); assert.throws(() => { - fs.statfs(blockedFileURL, () => {}); + fs.statfsSync(blockedFileURL); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(blockedFile), })); -} +} \ No newline at end of file diff --git a/test/fixtures/permission/fs-symlink-target-write.js b/test/fixtures/permission/fs-symlink-target-write.js index 2783e6f82f397c..c17d674d59ee97 100644 --- a/test/fixtures/permission/fs-symlink-target-write.js +++ b/test/fixtures/permission/fs-symlink-target-write.js @@ -23,18 +23,14 @@ const writeOnlyFolder = process.env.WRITEONLYFOLDER; { // App won't be able to symlink from a readOnlyFolder assert.throws(() => { - fs.symlink(path.join(readOnlyFolder, 'file'), path.join(readWriteFolder, 'link-to-read-only'), 'file', (err) => { - assert.ifError(err); - }); + fs.symlinkSync(path.join(readOnlyFolder, 'file'), path.join(readWriteFolder, 'link-to-read-only'), 'file'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', resource: path.toNamespacedPath(path.join(readOnlyFolder, 'file')), })); assert.throws(() => { - fs.link(path.join(readOnlyFolder, 'file'), path.join(readWriteFolder, 'link-to-read-only'), (err) => { - assert.ifError(err); - }); + fs.linkSync(path.join(readOnlyFolder, 'file'), path.join(readWriteFolder, 'link-to-read-only')); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', @@ -45,11 +41,7 @@ const writeOnlyFolder = process.env.WRITEONLYFOLDER; fs.symlink(path.join(readWriteFolder, 'file'), path.join(writeOnlyFolder, 'link-to-read-write'), 'file', (err) => { assert.ifError(err); // App will won't be able to read the symlink - assert.throws(() => { - fs.readFile(path.join(writeOnlyFolder, 'link-to-read-write'), (err) => { - assert.ifError(err); - }); - }, common.expectsError({ + fs.readFile(path.join(writeOnlyFolder, 'link-to-read-write'), common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', })); @@ -60,11 +52,7 @@ const writeOnlyFolder = process.env.WRITEONLYFOLDER; fs.link(path.join(readWriteFolder, 'file'), path.join(writeOnlyFolder, 'link-to-read-write2'), (err) => { assert.ifError(err); // App will won't be able to read the link - assert.throws(() => { - fs.readFile(path.join(writeOnlyFolder, 'link-to-read-write2'), (err) => { - assert.ifError(err); - }); - }, common.expectsError({ + fs.readFile(path.join(writeOnlyFolder, 'link-to-read-write2'), common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', })); @@ -75,21 +63,17 @@ const writeOnlyFolder = process.env.WRITEONLYFOLDER; // App won't be able to symlink to a readOnlyFolder assert.throws(() => { - fs.symlink(path.join(readWriteFolder, 'file'), path.join(readOnlyFolder, 'link-to-read-only'), 'file', (err) => { - assert.ifError(err); - }); + fs.symlinkSync(path.join(readWriteFolder, 'file'), path.join(readOnlyFolder, 'link-to-read-only'), 'file'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', resource: path.toNamespacedPath(path.join(readOnlyFolder, 'link-to-read-only')), })); assert.throws(() => { - fs.link(path.join(readWriteFolder, 'file'), path.join(readOnlyFolder, 'link-to-read-only'), (err) => { - assert.ifError(err); - }); + fs.linkSync(path.join(readWriteFolder, 'file'), path.join(readOnlyFolder, 'link-to-read-only')); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', resource: path.toNamespacedPath(path.join(readOnlyFolder, 'link-to-read-only')), })); -} +} \ No newline at end of file diff --git a/test/fixtures/permission/fs-symlink.js b/test/fixtures/permission/fs-symlink.js index 430b2f9b09574c..4cf3b45f0ebcfb 100644 --- a/test/fixtures/permission/fs-symlink.js +++ b/test/fixtures/permission/fs-symlink.js @@ -37,17 +37,13 @@ const symlinkFromBlockedFile = process.env.EXISTINGSYMLINK; { // App doesn’t have access to the BLOCKFOLDER assert.throws(() => { - fs.opendir(blockedFolder, (err) => { - assert.ifError(err); - }); + fs.opendirSync(blockedFolder); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', })); assert.throws(() => { - fs.writeFile(blockedFolder + '/new-file', 'data', (err) => { - assert.ifError(err); - }); + fs.writeFileSync(blockedFolder + '/new-file', 'data'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', @@ -55,17 +51,13 @@ const symlinkFromBlockedFile = process.env.EXISTINGSYMLINK; // App doesn’t have access to the BLOCKEDFILE folder assert.throws(() => { - fs.readFile(blockedFile, (err) => { - assert.ifError(err); - }); + fs.readFileSync(blockedFile); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', })); assert.throws(() => { - fs.appendFile(blockedFile, 'data', (err) => { - assert.ifError(err); - }); + fs.appendFileSync(blockedFile, 'data'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', @@ -73,17 +65,13 @@ const symlinkFromBlockedFile = process.env.EXISTINGSYMLINK; // App won't be able to symlink REGULARFILE to BLOCKFOLDER/asdf assert.throws(() => { - fs.symlink(regularFile, blockedFolder + '/asdf', 'file', (err) => { - assert.ifError(err); - }); + fs.symlinkSync(regularFile, blockedFolder + '/asdf', 'file'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', })); assert.throws(() => { - fs.link(regularFile, blockedFolder + '/asdf', (err) => { - assert.ifError(err); - }); + fs.linkSync(regularFile, blockedFolder + '/asdf'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', @@ -91,19 +79,15 @@ const symlinkFromBlockedFile = process.env.EXISTINGSYMLINK; // App won't be able to symlink BLOCKEDFILE to REGULARDIR assert.throws(() => { - fs.symlink(blockedFile, path.join(__dirname, '/asdf'), 'file', (err) => { - assert.ifError(err); - }); + fs.symlinkSync(blockedFile, path.join(__dirname, '/asdf'), 'file'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', })); assert.throws(() => { - fs.link(blockedFile, path.join(__dirname, '/asdf'), (err) => { - assert.ifError(err); - }); + fs.linkSync(blockedFile, path.join(__dirname, '/asdf')); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', })); -} +} \ No newline at end of file diff --git a/test/fixtures/permission/fs-traversal.js b/test/fixtures/permission/fs-traversal.js index 5a127f75474da8..6b35331d8f061f 100644 --- a/test/fixtures/permission/fs-traversal.js +++ b/test/fixtures/permission/fs-traversal.js @@ -28,11 +28,7 @@ const uint8ArrayTraversalPath = new TextEncoder().encode(traversalPath); } { - assert.throws(() => { - fs.writeFile(traversalPath, 'test', (error) => { - assert.ifError(error); - }); - }, common.expectsError({ + fs.writeFile(traversalPath, 'test', common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', resource: path.toNamespacedPath(resolve(traversalPath)), @@ -40,11 +36,7 @@ const uint8ArrayTraversalPath = new TextEncoder().encode(traversalPath); } { - assert.throws(() => { - fs.readFile(traversalPath, (error) => { - assert.ifError(error); - }); - }, common.expectsError({ + fs.readFile(traversalPath, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: path.toNamespacedPath(resolve(traversalPath)), @@ -53,34 +45,24 @@ const uint8ArrayTraversalPath = new TextEncoder().encode(traversalPath); { assert.throws(() => { - fs.mkdtempSync(traversalFolderPath, (error) => { - assert.ifError(error); - }); - }, common.expectsError({ + fs.mkdtempSync(traversalFolderPath) + }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', resource: resolve(traversalFolderPath + 'XXXXXX'), - })); + }); } { - assert.throws(() => { - fs.mkdtemp(traversalFolderPath, (error) => { - assert.ifError(error); - }); - }, common.expectsError({ - code: 'ERR_ACCESS_DENIED', - permission: 'FileSystemWrite', - resource: resolve(traversalFolderPath + 'XXXXXX'), - })); + fs.mkdtemp(traversalFolderPath, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemWrite', + resource: resolve(traversalFolderPath + 'XXXXXX'), + })); } { - assert.throws(() => { - fs.readFile(bufferTraversalPath, (error) => { - assert.ifError(error); - }); - }, common.expectsError({ + fs.readFile(bufferTraversalPath, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: resolve(traversalPath), @@ -88,11 +70,7 @@ const uint8ArrayTraversalPath = new TextEncoder().encode(traversalPath); } { - assert.throws(() => { - fs.readFile(uint8ArrayTraversalPath, (error) => { - assert.ifError(error); - }); - }, common.expectsError({ + fs.readFile(uint8ArrayTraversalPath, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', resource: resolve(traversalPath), @@ -111,7 +89,7 @@ const uint8ArrayTraversalPath = new TextEncoder().encode(traversalPath); } catch { } assert.throws(() => { - fs.readFile(cwd, common.mustNotCall()); + fs.readFileSync(cwd); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', @@ -136,7 +114,7 @@ const uint8ArrayTraversalPath = new TextEncoder().encode(traversalPath); assert.strictEqual(Buffer.from(resolve(traversalPathWithExtraChars)).toString(), traversalPath); assert.throws(() => { - fs.readFile(traversalPathWithExtraBytes, common.mustNotCall()); + fs.readFileSync(traversalPathWithExtraBytes); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', @@ -144,7 +122,7 @@ const uint8ArrayTraversalPath = new TextEncoder().encode(traversalPath); })); assert.throws(() => { - fs.readFile(new TextEncoder().encode(traversalPathWithExtraBytes.toString()), common.mustNotCall()); + fs.readFileSync(new TextEncoder().encode(traversalPathWithExtraBytes.toString())); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', @@ -157,4 +135,4 @@ const uint8ArrayTraversalPath = new TextEncoder().encode(traversalPath); assert.ok(!process.permission.has('fs.write', traversalPath)); assert.ok(!process.permission.has('fs.read', traversalFolderPath)); assert.ok(!process.permission.has('fs.write', traversalFolderPath)); -} +} \ No newline at end of file diff --git a/test/fixtures/permission/fs-wildcard.js b/test/fixtures/permission/fs-wildcard.js index 33d6e2a4ab1c21..d069d410806d7f 100644 --- a/test/fixtures/permission/fs-wildcard.js +++ b/test/fixtures/permission/fs-wildcard.js @@ -7,29 +7,40 @@ const fs = require('fs'); { assert.throws(() => { - fs.readFile('/test.txt', () => {}); + fs.readFileSync('/test.txt'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', })); // doesNotThrow - fs.readFile('/tmp/foo/file', () => {}); + fs.readFile('/tmp/foo/file', (err) => { + // Will throw ENOENT + assert.notEqual(err.code, 'ERR_ACCESS_DENIED'); + }); } { // doesNotThrow - fs.readFile('/example/foo/file', () => {}); - fs.readFile('/example/foo2/file', () => {}); - fs.readFile('/example/foo2', () => {}); + fs.readFile('/example/foo/file', (err) => { + assert.notEqual(err.code, 'ERR_ACCESS_DENIED'); + }); + + fs.readFile('/example/foo2/file', (err) => { + assert.notEqual(err.code, 'ERR_ACCESS_DENIED'); + }); + + fs.readFile('/example/foo2', (err) => { + assert.notEqual(err.code, 'ERR_ACCESS_DENIED'); + }); assert.throws(() => { - fs.readFile('/example/fo/foo2.js', () => {}); + fs.readFileSync('/example/fo/foo2.js'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', })); assert.throws(() => { - fs.readFile('/example/for', () => {}); + fs.readFileSync('/example/for'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', @@ -38,12 +49,18 @@ const fs = require('fs'); { // doesNotThrow - fs.readFile('/example/bar/file', () => {}); - fs.readFile('/example/bar2/file', () => {}); - fs.readFile('/example/bar', () => {}); + fs.readFile('/example/bar/file', (err) => { + assert.notEqual(err.code, 'ERR_ACCESS_DENIED'); + }); + fs.readFile('/example/bar2/file', (err) => { + assert.notEqual(err.code, 'ERR_ACCESS_DENIED'); + }); + fs.readFile('/example/bar', (err) => { + assert.notEqual(err.code, 'ERR_ACCESS_DENIED'); + }); assert.throws(() => { - fs.readFile('/example/ba/foo2.js', () => {}); + fs.readFileSync('/example/ba/foo2.js'); }, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemRead', @@ -51,7 +68,13 @@ const fs = require('fs'); } { - fs.readFile('/folder/a/subfolder/b', () => {}); - fs.readFile('/folder/a/subfolder/b/c.txt', () => {}); - fs.readFile('/folder/a/foo2.js', () => {}); -} + fs.readFile('/folder/a/subfolder/b', (err) => { + assert.notEqual(err.code, 'ERR_ACCESS_DENIED'); + }); + fs.readFile('/folder/a/subfolder/b/c.txt', (err) => { + assert.notEqual(err.code, 'ERR_ACCESS_DENIED'); + }); + fs.readFile('/folder/a/foo2.js', (err) => { + assert.notEqual(err.code, 'ERR_ACCESS_DENIED'); + }); +} \ No newline at end of file diff --git a/test/fixtures/permission/fs-write.js b/test/fixtures/permission/fs-write.js index 5e7e1ac588ee76..828f953ea2ce42 100644 --- a/test/fixtures/permission/fs-write.js +++ b/test/fixtures/permission/fs-write.js @@ -25,21 +25,26 @@ const absoluteProtectedFolder = path.resolve(relativeProtectedFolder); // fs.writeFile { assert.throws(() => { - fs.writeFile(blockedFile, 'example', () => {}); + fs.writeFileSync(blockedFile, 'example'); }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', resource: path.toNamespacedPath(blockedFile), }); + fs.writeFile(blockedFile, 'example', common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemWrite', + resource: path.toNamespacedPath(blockedFile), + })); assert.throws(() => { - fs.writeFile(blockedFileURL, 'example', () => {}); + fs.writeFileSync(blockedFileURL, 'example'); }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', resource: path.toNamespacedPath(blockedFile), }); assert.throws(() => { - fs.writeFile(relativeProtectedFile, 'example', () => {}); + fs.writeFileSync(relativeProtectedFile, 'example'); }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', @@ -47,7 +52,7 @@ const absoluteProtectedFolder = path.resolve(relativeProtectedFolder); }); assert.throws(() => { - fs.writeFile(path.join(blockedFolder, 'anyfile'), 'example', () => {}); + fs.writeFileSync(path.join(blockedFolder, 'anyfile'), 'example'); }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', @@ -170,59 +175,50 @@ const absoluteProtectedFolder = path.resolve(relativeProtectedFolder); code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', }); - assert.throws(() => { - fs.mkdtemp(path.join(relativeProtectedFolder, 'any-folder'), (err) => { - assert.ifError(err); - }); - },{ + fs.mkdtemp(path.join(relativeProtectedFolder, 'any-folder'), common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', - }); + })); } // fs.rename { assert.throws(() => { - fs.rename(blockedFile, path.join(blockedFile, 'renamed'), (err) => { - assert.ifError(err); - }); - },{ + fs.renameSync(blockedFile, path.join(blockedFile, 'renamed')); + }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', resource: path.toNamespacedPath(blockedFile), }); + fs.rename(blockedFile, path.join(blockedFile, 'renamed'), common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemWrite', + resource: path.toNamespacedPath(blockedFile), + })); assert.throws(() => { - fs.rename(blockedFileURL, path.join(blockedFile, 'renamed'), (err) => { - assert.ifError(err); - }); + fs.renameSync(blockedFileURL, path.join(blockedFile, 'renamed')); }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', resource: path.toNamespacedPath(blockedFile), }); assert.throws(() => { - fs.rename(relativeProtectedFile, path.join(relativeProtectedFile, 'renamed'), (err) => { - assert.ifError(err); - }); + fs.renameSync(relativeProtectedFile, path.join(relativeProtectedFile, 'renamed')); },{ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', resource: path.toNamespacedPath(absoluteProtectedFile), }); assert.throws(() => { - fs.rename(blockedFile, path.join(regularFolder, 'renamed'), (err) => { - assert.ifError(err); - }); - },{ + fs.renameSync(blockedFile, path.join(regularFolder, 'renamed')); + }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', resource: path.toNamespacedPath(blockedFile), }); assert.throws(() => { - fs.rename(regularFile, path.join(blockedFolder, 'renamed'), (err) => { - assert.ifError(err); - }); + fs.renameSync(regularFile, path.join(blockedFolder, 'renamed')); },{ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', @@ -246,6 +242,11 @@ const absoluteProtectedFolder = path.resolve(relativeProtectedFolder); permission: 'FileSystemWrite', resource: path.toNamespacedPath(path.join(absoluteProtectedFolder, 'any-file')), }); + fs.copyFile(regularFile, path.join(relativeProtectedFolder, 'any-file'), common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemWrite', + resource: path.toNamespacedPath(path.join(absoluteProtectedFolder, 'any-file')), + })); } // fs.cp @@ -288,18 +289,14 @@ const absoluteProtectedFolder = path.resolve(relativeProtectedFolder); { // Extra flags should not enable trivially bypassing all restrictions. // See https://github.com/nodejs/node/issues/47090. - assert.throws(() => { - fs.open(blockedFile, fs.constants.O_RDWR | 0x10000000, common.mustNotCall()); - }, { + fs.open(blockedFile, fs.constants.O_RDWR | 0x10000000, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', - }); - assert.throws(() => { - fs.open(blockedFileURL, fs.constants.O_RDWR | 0x10000000, common.mustNotCall()); - }, { + })); + fs.open(blockedFileURL, fs.constants.O_RDWR | 0x10000000, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', - }); + })); assert.rejects(async () => { await fs.promises.open(blockedFile, fs.constants.O_RDWR | fs.constants.O_NOFOLLOW); }, { @@ -344,12 +341,10 @@ const absoluteProtectedFolder = path.resolve(relativeProtectedFolder); // fs.lchmod { if (common.isOSX) { - assert.throws(() => { - fs.lchmod(blockedFile, 0o755, common.mustNotCall()); - }, { + fs.lchmod(blockedFile, 0o755, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', - }); + })); assert.rejects(async () => { await fs.promises.lchmod(blockedFile, 0o755); }, { @@ -361,14 +356,12 @@ const absoluteProtectedFolder = path.resolve(relativeProtectedFolder); // fs.appendFile { - assert.throws(() => { - fs.appendFile(blockedFile, 'new data', common.mustNotCall()); - }, { + fs.appendFile(blockedFile, 'new data', common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', - }); + })); assert.throws(() => { - fs.appendFile(blockedFileURL, 'new data', common.mustNotCall()); + fs.appendFileSync(blockedFileURL, 'new data'); }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', @@ -383,85 +376,89 @@ const absoluteProtectedFolder = path.resolve(relativeProtectedFolder); // fs.chown { - assert.throws(() => { - fs.chown(blockedFile, 1541, 999, common.mustNotCall()); - }, { + fs.chown(blockedFile, 1541, 999, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', - }); + })); assert.throws(() => { - fs.chown(blockedFileURL, 1541, 999, common.mustNotCall()); - }, { - code: 'ERR_ACCESS_DENIED', - permission: 'FileSystemWrite', - }); - assert.rejects(async () => { - await fs.promises.chown(blockedFile, 1541, 999); + fs.chownSync(blockedFileURL, 1541, 999); }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', }); + // TODO(@RafaelGSS): Uncaught Exception somehow? + // assert.rejects(async () => { + // return fs.promises.chown(blockedFile, 1541, 999); + // }, { + // code: 'ERR_ACCESS_DENIED', + // permission: 'FileSystemWrite', + // }); } // fs.lchown { - assert.throws(() => { - fs.lchown(blockedFile, 1541, 999, common.mustNotCall()); - }, { + fs.lchown(blockedFile, 1541, 999, common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', - }); + })); assert.throws(() => { - fs.lchown(blockedFileURL, 1541, 999, common.mustNotCall()); - }, { - code: 'ERR_ACCESS_DENIED', - permission: 'FileSystemWrite', - }); - assert.rejects(async () => { - await fs.promises.lchown(blockedFile, 1541, 999); + fs.lchownSync(blockedFileURL, 1541, 999); }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', }); + // TODO(@RafaelGSS): Uncaught Exception somehow? + // assert.rejects(async () => { + // await fs.promises.lchown(blockedFile, 1541, 999); + // }, { + // code: 'ERR_ACCESS_DENIED', + // permission: 'FileSystemWrite', + // }); } // fs.link { assert.throws(() => { - fs.link(blockedFile, path.join(blockedFolder, '/linked'), common.mustNotCall()); + fs.linkSync(blockedFile, path.join(blockedFolder, '/linked')); }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', }); - assert.throws(() => { - fs.link(blockedFileURL, path.join(blockedFolder, '/linked'), common.mustNotCall()); - }, { + fs.link(blockedFile, path.join(blockedFolder, '/linked'), common.expectsError({ code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', - }); - assert.rejects(async () => { - await fs.promises.link(blockedFile, path.join(blockedFolder, '/linked')); + })); + assert.throws(() => { + fs.linkSync(blockedFileURL, path.join(blockedFolder, '/linked')); }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', }); + // TODO(@RafaelGSS): Uncaught Exception somehow? + // assert.rejects(async () => { + // await fs.promises.link(blockedFile, path.join(blockedFolder, '/linked')); + // }, { + // code: 'ERR_ACCESS_DENIED', + // permission: 'FileSystemWrite', + // }); } // fs.unlink { assert.throws(() => { - fs.unlink(blockedFile, (err) => { - assert.ifError(err); - }); + fs.unlinkSync(blockedFile); }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', resource: path.toNamespacedPath(blockedFile), }); + fs.unlink(blockedFile, common.expectsError({ + code: 'ERR_ACCESS_DENIED', + permission: 'FileSystemWrite', + resource: path.toNamespacedPath(blockedFile), + })); assert.throws(() => { - fs.unlink(blockedFileURL, (err) => { - assert.ifError(err); - }); + fs.unlinkSync(blockedFileURL); }, { code: 'ERR_ACCESS_DENIED', permission: 'FileSystemWrite', diff --git a/test/fixtures/permission/loader/index.js b/test/fixtures/permission/loader/index.js index d0bb5ebde606e8..f8395e6dd17205 100644 --- a/test/fixtures/permission/loader/index.js +++ b/test/fixtures/permission/loader/index.js @@ -1,3 +1,3 @@ const fs = require('node:fs'); -fs.readFile('/etc/passwd', () => {}); +fs.readFileSync('/etc/passwd'); \ No newline at end of file diff --git a/test/fixtures/test-runner/output/force_exit.js b/test/fixtures/test-runner/output/force_exit.js new file mode 100644 index 00000000000000..a629f972a2f0ef --- /dev/null +++ b/test/fixtures/test-runner/output/force_exit.js @@ -0,0 +1,27 @@ +// Flags: --test-force-exit --test-reporter=spec +'use strict'; +const { after, afterEach, before, beforeEach, test } = require('node:test'); + +before(() => { + console.log('BEFORE'); +}); + +beforeEach(() => { + console.log('BEFORE EACH'); +}); + +after(() => { + console.log('AFTER'); +}); + +afterEach(() => { + console.log('AFTER EACH'); +}); + +test('passes but oops', () => { + setTimeout(() => { + throw new Error('this should not have a chance to be thrown'); + }, 1000); +}); + +test('also passes'); diff --git a/test/fixtures/test-runner/output/force_exit.snapshot b/test/fixtures/test-runner/output/force_exit.snapshot new file mode 100644 index 00000000000000..b45901f80c5be8 --- /dev/null +++ b/test/fixtures/test-runner/output/force_exit.snapshot @@ -0,0 +1,16 @@ +BEFORE +BEFORE EACH +AFTER EACH +BEFORE EACH +AFTER EACH +AFTER +✔ passes but oops (*ms) +✔ also passes (*ms) +ℹ tests 2 +ℹ suites 0 +ℹ pass 2 +ℹ fail 0 +ℹ cancelled 0 +ℹ skipped 0 +ℹ todo 0 +ℹ duration_ms * diff --git a/test/fixtures/test-runner/output/name_pattern.js b/test/fixtures/test-runner/output/name_pattern.js index 10e7619b9cfcb9..6994f7b54fc9a7 100644 --- a/test/fixtures/test-runner/output/name_pattern.js +++ b/test/fixtures/test-runner/output/name_pattern.js @@ -65,3 +65,13 @@ describe('no', function() { it('yes', () => {}); }); }); + +describe('no with todo', { todo: true }, () => { + it('no', () => {}); + it('yes', () => {}); + + describe('maybe', function() { + it('no', () => {}); + it('yes', () => {}); + }); +}); diff --git a/test/fixtures/test-runner/output/name_pattern.snapshot b/test/fixtures/test-runner/output/name_pattern.snapshot index bd53cc1fd2b89e..d4a0d459def1e6 100644 --- a/test/fixtures/test-runner/output/name_pattern.snapshot +++ b/test/fixtures/test-runner/output/name_pattern.snapshot @@ -171,12 +171,46 @@ ok 15 - no duration_ms: * type: 'suite' ... -1..15 -# tests 21 -# suites 10 -# pass 13 +# Subtest: no with todo + # Subtest: no + ok 1 - no # SKIP test name does not match pattern + --- + duration_ms: * + ... + # Subtest: yes + ok 2 - yes + --- + duration_ms: * + ... + # Subtest: maybe + # Subtest: no + ok 1 - no # SKIP test name does not match pattern + --- + duration_ms: * + ... + # Subtest: yes + ok 2 - yes + --- + duration_ms: * + ... + 1..2 + ok 3 - maybe + --- + duration_ms: * + type: 'suite' + ... + 1..3 +ok 16 - no with todo # TODO test name does not match pattern + --- + duration_ms: * + type: 'suite' + ... +1..16 +# tests 25 +# suites 12 +# pass 15 # fail 0 # cancelled 0 -# skipped 8 +# skipped 10 # todo 0 # duration_ms * diff --git a/test/fixtures/test-runner/output/source_mapped_locations.mjs b/test/fixtures/test-runner/output/source_mapped_locations.mjs new file mode 100644 index 00000000000000..82e33499284171 --- /dev/null +++ b/test/fixtures/test-runner/output/source_mapped_locations.mjs @@ -0,0 +1,7 @@ +// Flags: --enable-source-maps +import { test } from 'node:test'; +import { strictEqual } from 'node:assert'; +test('fails', () => { + strictEqual(1, 2); +}); +//# sourceMappingURL=source_mapped_locations.mjs.map diff --git a/test/fixtures/test-runner/output/source_mapped_locations.mjs.map b/test/fixtures/test-runner/output/source_mapped_locations.mjs.map new file mode 100644 index 00000000000000..991dd95820c4ce --- /dev/null +++ b/test/fixtures/test-runner/output/source_mapped_locations.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"source_mapped_locations.mjs","sourceRoot":"","sources":["source_mapped_locations.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;IACjB,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"} diff --git a/test/fixtures/test-runner/output/source_mapped_locations.snapshot b/test/fixtures/test-runner/output/source_mapped_locations.snapshot new file mode 100644 index 00000000000000..29b70fd0d08378 --- /dev/null +++ b/test/fixtures/test-runner/output/source_mapped_locations.snapshot @@ -0,0 +1,36 @@ +TAP version 13 +# Subtest: fails +not ok 1 - fails + --- + duration_ms: * + location: '/test/fixtures/test-runner/output/source_mapped_locations.ts:5:1' + failureType: 'testCodeFailure' + error: |- + Expected values to be strictly equal: + + 1 !== 2 + + code: 'ERR_ASSERTION' + name: 'AssertionError' + expected: 2 + actual: 1 + operator: 'strictEqual' + stack: |- + * + * + * + * + * + * + * + * + ... +1..1 +# tests 1 +# suites 0 +# pass 0 +# fail 1 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms * diff --git a/test/fixtures/test-runner/output/source_mapped_locations.ts b/test/fixtures/test-runner/output/source_mapped_locations.ts new file mode 100644 index 00000000000000..d237df16396bf0 --- /dev/null +++ b/test/fixtures/test-runner/output/source_mapped_locations.ts @@ -0,0 +1,7 @@ +// Flags: --enable-source-maps +import { test } from 'node:test'; +import { strictEqual } from 'node:assert'; + +test('fails', () => { + strictEqual(1, 2); +}); diff --git a/test/fixtures/test-runner/throws_sync_and_async.js b/test/fixtures/test-runner/throws_sync_and_async.js new file mode 100644 index 00000000000000..50ed81b4acf511 --- /dev/null +++ b/test/fixtures/test-runner/throws_sync_and_async.js @@ -0,0 +1,10 @@ +'use strict'; +const { test } = require('node:test'); + +test('fails and schedules more work', () => { + setTimeout(() => { + throw new Error('this should not have a chance to be thrown'); + }, 1000); + + throw new Error('fails'); +}); diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md index 69c7a905dd0fef..2d610caa8e412a 100644 --- a/test/fixtures/wpt/README.md +++ b/test/fixtures/wpt/README.md @@ -26,7 +26,7 @@ Last update: - performance-timeline: https://github.com/web-platform-tests/wpt/tree/17ebc3aea0/performance-timeline - resource-timing: https://github.com/web-platform-tests/wpt/tree/22d38586d0/resource-timing - resources: https://github.com/web-platform-tests/wpt/tree/919874f84f/resources -- streams: https://github.com/web-platform-tests/wpt/tree/517e945bbf/streams +- streams: https://github.com/web-platform-tests/wpt/tree/a8872d92b1/streams - url: https://github.com/web-platform-tests/wpt/tree/c2d7e70b52/url - user-timing: https://github.com/web-platform-tests/wpt/tree/5ae85bf826/user-timing - wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/cde25e7e3c/wasm/jsapi diff --git a/test/fixtures/wpt/streams/piping/abort.any.js b/test/fixtures/wpt/streams/piping/abort.any.js index 503de9dcaf0893..c9929df91cf688 100644 --- a/test/fixtures/wpt/streams/piping/abort.any.js +++ b/test/fixtures/wpt/streams/piping/abort.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/recording-streams.js // META: script=../resources/test-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/piping/close-propagation-backward.any.js b/test/fixtures/wpt/streams/piping/close-propagation-backward.any.js index 5ea47ab85c0c1f..25bd475ed13e77 100644 --- a/test/fixtures/wpt/streams/piping/close-propagation-backward.any.js +++ b/test/fixtures/wpt/streams/piping/close-propagation-backward.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/streams/piping/close-propagation-forward.any.js b/test/fixtures/wpt/streams/piping/close-propagation-forward.any.js index 71b6e262840090..0ec94f80abf04b 100644 --- a/test/fixtures/wpt/streams/piping/close-propagation-forward.any.js +++ b/test/fixtures/wpt/streams/piping/close-propagation-forward.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/streams/piping/crashtests/cross-piping.html b/test/fixtures/wpt/streams/piping/crashtests/cross-piping.html new file mode 100644 index 00000000000000..712d5ecebef8ff --- /dev/null +++ b/test/fixtures/wpt/streams/piping/crashtests/cross-piping.html @@ -0,0 +1,12 @@ + + diff --git a/test/fixtures/wpt/streams/piping/error-propagation-backward.any.js b/test/fixtures/wpt/streams/piping/error-propagation-backward.any.js index ec74592f86effe..f786469d6c1d40 100644 --- a/test/fixtures/wpt/streams/piping/error-propagation-backward.any.js +++ b/test/fixtures/wpt/streams/piping/error-propagation-backward.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/streams/piping/error-propagation-forward.any.js b/test/fixtures/wpt/streams/piping/error-propagation-forward.any.js index 482da2f8a88e18..e9260f9ea22c41 100644 --- a/test/fixtures/wpt/streams/piping/error-propagation-forward.any.js +++ b/test/fixtures/wpt/streams/piping/error-propagation-forward.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/streams/piping/flow-control.any.js b/test/fixtures/wpt/streams/piping/flow-control.any.js index 09c4420f872adc..e2318da375ab90 100644 --- a/test/fixtures/wpt/streams/piping/flow-control.any.js +++ b/test/fixtures/wpt/streams/piping/flow-control.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/rs-utils.js // META: script=../resources/recording-streams.js diff --git a/test/fixtures/wpt/streams/piping/general-addition.any.js b/test/fixtures/wpt/streams/piping/general-addition.any.js index 2562b7064338ee..cf4aa9bea6a1a4 100644 --- a/test/fixtures/wpt/streams/piping/general-addition.any.js +++ b/test/fixtures/wpt/streams/piping/general-addition.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; promise_test(async t => { diff --git a/test/fixtures/wpt/streams/piping/general.any.js b/test/fixtures/wpt/streams/piping/general.any.js index bec3480f653944..09e01536325cca 100644 --- a/test/fixtures/wpt/streams/piping/general.any.js +++ b/test/fixtures/wpt/streams/piping/general.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/streams/piping/multiple-propagation.any.js b/test/fixtures/wpt/streams/piping/multiple-propagation.any.js index a78652fc06795e..9be828a23269a5 100644 --- a/test/fixtures/wpt/streams/piping/multiple-propagation.any.js +++ b/test/fixtures/wpt/streams/piping/multiple-propagation.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/streams/piping/pipe-through.any.js b/test/fixtures/wpt/streams/piping/pipe-through.any.js index 26b1cd26a3c82f..339cee19993346 100644 --- a/test/fixtures/wpt/streams/piping/pipe-through.any.js +++ b/test/fixtures/wpt/streams/piping/pipe-through.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/rs-utils.js // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js diff --git a/test/fixtures/wpt/streams/piping/then-interception.any.js b/test/fixtures/wpt/streams/piping/then-interception.any.js index 543f916d940d9a..fc48c368311478 100644 --- a/test/fixtures/wpt/streams/piping/then-interception.any.js +++ b/test/fixtures/wpt/streams/piping/then-interception.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/streams/piping/throwing-options.any.js b/test/fixtures/wpt/streams/piping/throwing-options.any.js index b9f906778f632b..186f8ded1968a4 100644 --- a/test/fixtures/wpt/streams/piping/throwing-options.any.js +++ b/test/fixtures/wpt/streams/piping/throwing-options.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; class ThrowingOptions { diff --git a/test/fixtures/wpt/streams/piping/transform-streams.any.js b/test/fixtures/wpt/streams/piping/transform-streams.any.js index caae9fbad8848a..e079bb637cad0d 100644 --- a/test/fixtures/wpt/streams/piping/transform-streams.any.js +++ b/test/fixtures/wpt/streams/piping/transform-streams.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; promise_test(() => { diff --git a/test/fixtures/wpt/streams/queuing-strategies.any.js b/test/fixtures/wpt/streams/queuing-strategies.any.js index fa959ebba28338..9efc4570cf2ee2 100644 --- a/test/fixtures/wpt/streams/queuing-strategies.any.js +++ b/test/fixtures/wpt/streams/queuing-strategies.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; const highWaterMarkConversions = new Map([ diff --git a/test/fixtures/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.js b/test/fixtures/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.js index 3322116b191840..afcc61e6800a28 100644 --- a/test/fixtures/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.js +++ b/test/fixtures/wpt/streams/readable-byte-streams/bad-buffers-and-views.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; promise_test(() => { diff --git a/test/fixtures/wpt/streams/readable-byte-streams/construct-byob-request.any.js b/test/fixtures/wpt/streams/readable-byte-streams/construct-byob-request.any.js index 8d460a1c81b7bd..a26f949ee29d94 100644 --- a/test/fixtures/wpt/streams/readable-byte-streams/construct-byob-request.any.js +++ b/test/fixtures/wpt/streams/readable-byte-streams/construct-byob-request.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/rs-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/readable-byte-streams/enqueue-with-detached-buffer.any.js b/test/fixtures/wpt/streams/readable-byte-streams/enqueue-with-detached-buffer.any.js index d2b37f00a9d697..92bd0a26a0ec05 100644 --- a/test/fixtures/wpt/streams/readable-byte-streams/enqueue-with-detached-buffer.any.js +++ b/test/fixtures/wpt/streams/readable-byte-streams/enqueue-with-detached-buffer.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm promise_test(async t => { const error = new Error('cannot proceed'); diff --git a/test/fixtures/wpt/streams/readable-byte-streams/general.any.js b/test/fixtures/wpt/streams/readable-byte-streams/general.any.js index dd4fdc855786f2..cdce2244c3c84b 100644 --- a/test/fixtures/wpt/streams/readable-byte-streams/general.any.js +++ b/test/fixtures/wpt/streams/readable-byte-streams/general.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/rs-utils.js // META: script=../resources/test-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/readable-byte-streams/non-transferable-buffers.any.js b/test/fixtures/wpt/streams/readable-byte-streams/non-transferable-buffers.any.js index e8ea3c4f966763..47d7b2e653e5ec 100644 --- a/test/fixtures/wpt/streams/readable-byte-streams/non-transferable-buffers.any.js +++ b/test/fixtures/wpt/streams/readable-byte-streams/non-transferable-buffers.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; promise_test(async t => { diff --git a/test/fixtures/wpt/streams/readable-byte-streams/respond-after-enqueue.any.js b/test/fixtures/wpt/streams/readable-byte-streams/respond-after-enqueue.any.js index b93cec97391e13..e51efa061a6511 100644 --- a/test/fixtures/wpt/streams/readable-byte-streams/respond-after-enqueue.any.js +++ b/test/fixtures/wpt/streams/readable-byte-streams/respond-after-enqueue.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; diff --git a/test/fixtures/wpt/streams/readable-byte-streams/tee.any.js b/test/fixtures/wpt/streams/readable-byte-streams/tee.any.js index 85844669cd9088..7dd5ba3f3fb013 100644 --- a/test/fixtures/wpt/streams/readable-byte-streams/tee.any.js +++ b/test/fixtures/wpt/streams/readable-byte-streams/tee.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/rs-utils.js // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js diff --git a/test/fixtures/wpt/streams/readable-streams/async-iterator.any.js b/test/fixtures/wpt/streams/readable-streams/async-iterator.any.js index 3ccaca17bc1ac7..4b674bea8430f3 100644 --- a/test/fixtures/wpt/streams/readable-streams/async-iterator.any.js +++ b/test/fixtures/wpt/streams/readable-streams/async-iterator.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/rs-utils.js // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js diff --git a/test/fixtures/wpt/streams/readable-streams/bad-strategies.any.js b/test/fixtures/wpt/streams/readable-streams/bad-strategies.any.js index 521fbffe3ab479..49fa4bdbece5b5 100644 --- a/test/fixtures/wpt/streams/readable-streams/bad-strategies.any.js +++ b/test/fixtures/wpt/streams/readable-streams/bad-strategies.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; test(() => { @@ -149,7 +149,9 @@ promise_test(() => { } ); - promises.push(rs.getReader().closed.catch(e => { + promises.push(rs.getReader().closed.then(() => { + assert_unreached('closed didn\'t throw'); + }, e => { assert_equals(e, theError, 'closed should reject with the error for ' + size); })); } @@ -157,3 +159,40 @@ promise_test(() => { return Promise.all(promises); }, 'Readable stream: invalid strategy.size return value'); + +promise_test(() => { + + const promises = []; + for (const size of [NaN, -Infinity, Infinity, -1]) { + let theError; + const rs = new ReadableStream( + { + pull(c) { + try { + c.enqueue('hi'); + assert_unreached('enqueue didn\'t throw'); + } catch (error) { + assert_equals(error.name, 'RangeError', 'enqueue should throw a RangeError for ' + size); + theError = error; + } + } + }, + { + size() { + return size; + }, + highWaterMark: 5 + } + ); + + promises.push(rs.getReader().closed.then(() => { + assert_unreached('closed didn\'t throw'); + }, e => { + assert_equals(e, theError, 'closed should reject with the error for ' + size); + })); + } + + return Promise.all(promises); + +}, 'Readable stream: invalid strategy.size return value when pulling'); + diff --git a/test/fixtures/wpt/streams/readable-streams/bad-underlying-sources.any.js b/test/fixtures/wpt/streams/readable-streams/bad-underlying-sources.any.js index e9cf4c924930b2..3d77b923d178a0 100644 --- a/test/fixtures/wpt/streams/readable-streams/bad-underlying-sources.any.js +++ b/test/fixtures/wpt/streams/readable-streams/bad-underlying-sources.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; diff --git a/test/fixtures/wpt/streams/readable-streams/cancel.any.js b/test/fixtures/wpt/streams/readable-streams/cancel.any.js index 800bd994417241..9915c1fb6330c1 100644 --- a/test/fixtures/wpt/streams/readable-streams/cancel.any.js +++ b/test/fixtures/wpt/streams/readable-streams/cancel.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/rs-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/readable-streams/constructor.any.js b/test/fixtures/wpt/streams/readable-streams/constructor.any.js index 608dc48cfa39d7..0b995f0cb16bde 100644 --- a/test/fixtures/wpt/streams/readable-streams/constructor.any.js +++ b/test/fixtures/wpt/streams/readable-streams/constructor.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; const error1 = new Error('error1'); diff --git a/test/fixtures/wpt/streams/readable-streams/count-queuing-strategy-integration.any.js b/test/fixtures/wpt/streams/readable-streams/count-queuing-strategy-integration.any.js index 02ac5bae5c2f8a..a8c1b91d0068e3 100644 --- a/test/fixtures/wpt/streams/readable-streams/count-queuing-strategy-integration.any.js +++ b/test/fixtures/wpt/streams/readable-streams/count-queuing-strategy-integration.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; test(() => { diff --git a/test/fixtures/wpt/streams/readable-streams/default-reader.any.js b/test/fixtures/wpt/streams/readable-streams/default-reader.any.js index 59d7ab2f74db63..f92862719e47c1 100644 --- a/test/fixtures/wpt/streams/readable-streams/default-reader.any.js +++ b/test/fixtures/wpt/streams/readable-streams/default-reader.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/rs-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/readable-streams/floating-point-total-queue-size.any.js b/test/fixtures/wpt/streams/readable-streams/floating-point-total-queue-size.any.js index 50cca3d951a942..8b88c21d7f0b53 100644 --- a/test/fixtures/wpt/streams/readable-streams/floating-point-total-queue-size.any.js +++ b/test/fixtures/wpt/streams/readable-streams/floating-point-total-queue-size.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; // Due to the limitations of floating-point precision, the calculation of desiredSize sometimes gives different answers diff --git a/test/fixtures/wpt/streams/readable-streams/from.any.js b/test/fixtures/wpt/streams/readable-streams/from.any.js index 04a03545ad5fe3..58ad4d4add127d 100644 --- a/test/fixtures/wpt/streams/readable-streams/from.any.js +++ b/test/fixtures/wpt/streams/readable-streams/from.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker,jsshell +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/readable-streams/garbage-collection.any.js b/test/fixtures/wpt/streams/readable-streams/garbage-collection.any.js index e578176777adaf..13bd1fb3437877 100644 --- a/test/fixtures/wpt/streams/readable-streams/garbage-collection.any.js +++ b/test/fixtures/wpt/streams/readable-streams/garbage-collection.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=/common/gc.js 'use strict'; diff --git a/test/fixtures/wpt/streams/readable-streams/general.any.js b/test/fixtures/wpt/streams/readable-streams/general.any.js index 2a32b27943c82f..eee3f62215eeb0 100644 --- a/test/fixtures/wpt/streams/readable-streams/general.any.js +++ b/test/fixtures/wpt/streams/readable-streams/general.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/rs-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/readable-streams/owning-type-message-port.any.js b/test/fixtures/wpt/streams/readable-streams/owning-type-message-port.any.js index e9961ce042256a..282c1f411485c0 100644 --- a/test/fixtures/wpt/streams/readable-streams/owning-type-message-port.any.js +++ b/test/fixtures/wpt/streams/readable-streams/owning-type-message-port.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/rs-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/readable-streams/owning-type-video-frame.any.js b/test/fixtures/wpt/streams/readable-streams/owning-type-video-frame.any.js index ec01fda0b3c737..b652f9c5fcb4b6 100644 --- a/test/fixtures/wpt/streams/readable-streams/owning-type-video-frame.any.js +++ b/test/fixtures/wpt/streams/readable-streams/owning-type-video-frame.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/rs-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/readable-streams/owning-type.any.js b/test/fixtures/wpt/streams/readable-streams/owning-type.any.js index 27a3dda894e4d6..34c2a55d5134a2 100644 --- a/test/fixtures/wpt/streams/readable-streams/owning-type.any.js +++ b/test/fixtures/wpt/streams/readable-streams/owning-type.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/rs-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/readable-streams/patched-global.any.js b/test/fixtures/wpt/streams/readable-streams/patched-global.any.js index a64a054a97f1f5..c208824c864469 100644 --- a/test/fixtures/wpt/streams/readable-streams/patched-global.any.js +++ b/test/fixtures/wpt/streams/readable-streams/patched-global.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; // Tests which patch the global environment are kept separate to avoid diff --git a/test/fixtures/wpt/streams/readable-streams/reentrant-strategies.any.js b/test/fixtures/wpt/streams/readable-streams/reentrant-strategies.any.js index b4988bc2433fd5..8ae7b98e8d5eef 100644 --- a/test/fixtures/wpt/streams/readable-streams/reentrant-strategies.any.js +++ b/test/fixtures/wpt/streams/readable-streams/reentrant-strategies.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/recording-streams.js // META: script=../resources/rs-utils.js // META: script=../resources/test-utils.js diff --git a/test/fixtures/wpt/streams/readable-streams/tee.any.js b/test/fixtures/wpt/streams/readable-streams/tee.any.js index 00397932f4b6e3..c2c2e482307211 100644 --- a/test/fixtures/wpt/streams/readable-streams/tee.any.js +++ b/test/fixtures/wpt/streams/readable-streams/tee.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/rs-utils.js // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js diff --git a/test/fixtures/wpt/streams/readable-streams/templated.any.js b/test/fixtures/wpt/streams/readable-streams/templated.any.js index ecae3f4d8b129f..dc75b805a10d63 100644 --- a/test/fixtures/wpt/streams/readable-streams/templated.any.js +++ b/test/fixtures/wpt/streams/readable-streams/templated.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/rs-test-templates.js 'use strict'; diff --git a/test/fixtures/wpt/streams/transferable/transform-stream-members.any.js b/test/fixtures/wpt/streams/transferable/transform-stream-members.any.js index fca060b0c05fa3..05914e12ccbe57 100644 --- a/test/fixtures/wpt/streams/transferable/transform-stream-members.any.js +++ b/test/fixtures/wpt/streams/transferable/transform-stream-members.any.js @@ -1,3 +1,5 @@ +// META: global=window,dedicatedworker,shadowrealm + const combinations = [ (t => [t, t.readable])(new TransformStream()), (t => [t.readable, t])(new TransformStream()), diff --git a/test/fixtures/wpt/streams/transform-streams/backpressure.any.js b/test/fixtures/wpt/streams/transform-streams/backpressure.any.js index 6befba41b79542..47a21fb7e71fed 100644 --- a/test/fixtures/wpt/streams/transform-streams/backpressure.any.js +++ b/test/fixtures/wpt/streams/transform-streams/backpressure.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/recording-streams.js // META: script=../resources/test-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/transform-streams/cancel.any.js b/test/fixtures/wpt/streams/transform-streams/cancel.any.js new file mode 100644 index 00000000000000..5c7fc4eae5d55b --- /dev/null +++ b/test/fixtures/wpt/streams/transform-streams/cancel.any.js @@ -0,0 +1,115 @@ +// META: global=window,worker,shadowrealm +// META: script=../resources/test-utils.js +'use strict'; + +const thrownError = new Error('bad things are happening!'); +thrownError.name = 'error1'; + +const originalReason = new Error('original reason'); +originalReason.name = 'error2'; + +promise_test(async t => { + let cancelled = undefined; + const ts = new TransformStream({ + cancel(reason) { + cancelled = reason; + } + }); + const res = await ts.readable.cancel(thrownError); + assert_equals(res, undefined, 'readable.cancel() should return undefined'); + assert_equals(cancelled, thrownError, 'transformer.cancel() should be called with the passed reason'); +}, 'cancelling the readable side should call transformer.cancel()'); + +promise_test(async t => { + const ts = new TransformStream({ + cancel(reason) { + assert_equals(reason, originalReason, 'transformer.cancel() should be called with the passed reason'); + throw thrownError; + } + }); + const writer = ts.writable.getWriter(); + const cancelPromise = ts.readable.cancel(originalReason); + await promise_rejects_exactly(t, thrownError, cancelPromise, 'readable.cancel() should reject with thrownError'); + await promise_rejects_exactly(t, thrownError, writer.closed, 'writer.closed should reject with thrownError'); +}, 'cancelling the readable side should reject if transformer.cancel() throws'); + +promise_test(async t => { + let aborted = undefined; + const ts = new TransformStream({ + cancel(reason) { + aborted = reason; + }, + flush: t.unreached_func('flush should not be called') + }); + const res = await ts.writable.abort(thrownError); + assert_equals(res, undefined, 'writable.abort() should return undefined'); + assert_equals(aborted, thrownError, 'transformer.abort() should be called with the passed reason'); +}, 'aborting the writable side should call transformer.abort()'); + +promise_test(async t => { + const ts = new TransformStream({ + cancel(reason) { + assert_equals(reason, originalReason, 'transformer.cancel() should be called with the passed reason'); + throw thrownError; + }, + flush: t.unreached_func('flush should not be called') + }); + const reader = ts.readable.getReader(); + const abortPromise = ts.writable.abort(originalReason); + await promise_rejects_exactly(t, thrownError, abortPromise, 'writable.abort() should reject with thrownError'); + await promise_rejects_exactly(t, thrownError, reader.closed, 'reader.closed should reject with thrownError'); +}, 'aborting the writable side should reject if transformer.cancel() throws'); + +promise_test(async t => { + const ts = new TransformStream({ + async cancel(reason) { + assert_equals(reason, originalReason, 'transformer.cancel() should be called with the passed reason'); + throw thrownError; + }, + flush: t.unreached_func('flush should not be called') + }); + const cancelPromise = ts.readable.cancel(originalReason); + const closePromise = ts.writable.close(); + await Promise.all([ + promise_rejects_exactly(t, thrownError, cancelPromise, 'cancelPromise should reject with thrownError'), + promise_rejects_exactly(t, thrownError, closePromise, 'closePromise should reject with thrownError'), + ]); +}, 'closing the writable side should reject if a parallel transformer.cancel() throws'); + +promise_test(async t => { + let controller; + const ts = new TransformStream({ + start(c) { + controller = c; + }, + async cancel(reason) { + assert_equals(reason, originalReason, 'transformer.cancel() should be called with the passed reason'); + controller.error(thrownError); + }, + flush: t.unreached_func('flush should not be called') + }); + const cancelPromise = ts.readable.cancel(originalReason); + const closePromise = ts.writable.close(); + await Promise.all([ + promise_rejects_exactly(t, thrownError, cancelPromise, 'cancelPromise should reject with thrownError'), + promise_rejects_exactly(t, thrownError, closePromise, 'closePromise should reject with thrownError'), + ]); +}, 'readable.cancel() and a parallel writable.close() should reject if a transformer.cancel() calls controller.error()'); + +promise_test(async t => { + let controller; + const ts = new TransformStream({ + start(c) { + controller = c; + }, + async cancel(reason) { + assert_equals(reason, originalReason, 'transformer.cancel() should be called with the passed reason'); + controller.error(thrownError); + }, + flush: t.unreached_func('flush should not be called') + }); + const cancelPromise = ts.writable.abort(originalReason); + await promise_rejects_exactly(t, thrownError, cancelPromise, 'cancelPromise should reject with thrownError'); + const closePromise = ts.readable.cancel(1); + await promise_rejects_exactly(t, thrownError, closePromise, 'closePromise should reject with thrownError'); +}, 'writable.abort() and readable.cancel() should reject if a transformer.cancel() calls controller.error()'); diff --git a/test/fixtures/wpt/streams/transform-streams/errors.any.js b/test/fixtures/wpt/streams/transform-streams/errors.any.js index 0cca4c75479d6d..bea060b6590818 100644 --- a/test/fixtures/wpt/streams/transform-streams/errors.any.js +++ b/test/fixtures/wpt/streams/transform-streams/errors.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js 'use strict'; @@ -9,7 +9,8 @@ promise_test(t => { const ts = new TransformStream({ transform() { throw thrownError; - } + }, + cancel: t.unreached_func('cancel should not be called') }); const reader = ts.readable.getReader(); @@ -34,7 +35,8 @@ promise_test(t => { }, flush() { throw thrownError; - } + }, + cancel: t.unreached_func('cancel should not be called') }); const reader = ts.readable.getReader(); @@ -54,13 +56,14 @@ promise_test(t => { ]); }, 'TransformStream errors thrown in flush put the writable and readable in an errored state'); -test(() => { +test(t => { new TransformStream({ start(c) { c.enqueue('a'); c.error(new Error('generic error')); assert_throws_js(TypeError, () => c.enqueue('b'), 'enqueue() should throw'); - } + }, + cancel: t.unreached_func('cancel should not be called') }); }, 'errored TransformStream should not enqueue new chunks'); @@ -72,7 +75,8 @@ promise_test(t => { }); }, transform: t.unreached_func('transform should not be called'), - flush: t.unreached_func('flush should not be called') + flush: t.unreached_func('flush should not be called'), + cancel: t.unreached_func('cancel should not be called') }); const writer = ts.writable.getWriter(); @@ -96,7 +100,8 @@ promise_test(t => { }); }, transform: t.unreached_func('transform should never be called if start() fails'), - flush: t.unreached_func('flush should never be called if start() fails') + flush: t.unreached_func('flush should never be called if start() fails'), + cancel: t.unreached_func('cancel should never be called if start() fails') }); const writer = ts.writable.getWriter(); @@ -202,9 +207,10 @@ promise_test(t => { return Promise.all([ abortPromise, cancelPromise, - promise_rejects_exactly(t, thrownError, writer.closed, 'writer.closed should reject with thrownError')]); -}, 'abort should set the close reason for the writable when it happens before cancel during start, but cancel should ' + - 'still succeed'); + promise_rejects_exactly(t, thrownError, writer.closed, 'writer.closed should reject'), + ]); +}, 'abort should set the close reason for the writable when it happens before cancel during start, and cancel should ' + + 'reject'); promise_test(t => { let resolveTransform; @@ -251,13 +257,26 @@ promise_test(t => { controller = c; } }); - const cancelPromise = ts.readable.cancel(thrownError); - controller.error(ignoredError); + const cancelPromise = ts.readable.cancel(ignoredError); + controller.error(thrownError); return Promise.all([ cancelPromise, promise_rejects_exactly(t, thrownError, ts.writable.getWriter().closed, 'closed should reject with thrownError') ]); -}, 'controller.error() should do nothing after readable.cancel()'); +}, 'controller.error() should close writable immediately after readable.cancel()'); + +promise_test(t => { + let controller; + const ts = new TransformStream({ + start(c) { + controller = c; + } + }); + return ts.readable.cancel(thrownError).then(() => { + controller.error(ignoredError); + return promise_rejects_exactly(t, thrownError, ts.writable.getWriter().closed, 'closed should reject with thrownError'); + }); +}, 'controller.error() should do nothing after readable.cancel() resolves'); promise_test(t => { let controller; diff --git a/test/fixtures/wpt/streams/transform-streams/flush.any.js b/test/fixtures/wpt/streams/transform-streams/flush.any.js index 9287f6f5eb78eb..c95d8ae1186518 100644 --- a/test/fixtures/wpt/streams/transform-streams/flush.any.js +++ b/test/fixtures/wpt/streams/transform-streams/flush.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js 'use strict'; @@ -129,3 +129,18 @@ promise_test(t => { }); return promise_rejects_exactly(t, error1, ts.writable.getWriter().close(), 'close() should reject'); }, 'error() during flush should cause writer.close() to reject'); + +promise_test(async t => { + let flushed = false; + const ts = new TransformStream({ + flush() { + flushed = true; + }, + cancel: t.unreached_func('cancel should not be called') + }); + const closePromise = ts.writable.close(); + await delay(0); + const cancelPromise = ts.readable.cancel(error1); + await Promise.all([closePromise, cancelPromise]); + assert_equals(flushed, true, 'transformer.flush() should be called'); +}, 'closing the writable side should call transformer.flush() and a parallel readable.cancel() should not reject'); diff --git a/test/fixtures/wpt/streams/transform-streams/general.any.js b/test/fixtures/wpt/streams/transform-streams/general.any.js index c95691f7bf49df..a40ef30843ec4d 100644 --- a/test/fixtures/wpt/streams/transform-streams/general.any.js +++ b/test/fixtures/wpt/streams/transform-streams/general.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/rs-utils.js 'use strict'; @@ -388,9 +388,24 @@ promise_test(t => { controller.terminate(); return Promise.all([ cancelPromise, - promise_rejects_exactly(t, cancelReason, ts.writable.getWriter().closed, 'closed should reject with cancelReason') + promise_rejects_js(t, TypeError, ts.writable.getWriter().closed, 'closed should reject with TypeError') ]); -}, 'terminate() should do nothing after readable.cancel()'); +}, 'terminate() should abort writable immediately after readable.cancel()'); + +promise_test(t => { + let controller; + const ts = new TransformStream({ + start(c) { + controller = c; + } + }); + const cancelReason = { name: 'cancelReason' }; + return ts.readable.cancel(cancelReason).then(() => { + controller.terminate(); + return promise_rejects_exactly(t, cancelReason, ts.writable.getWriter().closed, 'closed should reject with TypeError'); + }) +}, 'terminate() should do nothing after readable.cancel() resolves'); + promise_test(() => { let calls = 0; diff --git a/test/fixtures/wpt/streams/transform-streams/lipfuzz.any.js b/test/fixtures/wpt/streams/transform-streams/lipfuzz.any.js index f9f148aaf1c6a4..e334705db44354 100644 --- a/test/fixtures/wpt/streams/transform-streams/lipfuzz.any.js +++ b/test/fixtures/wpt/streams/transform-streams/lipfuzz.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; class LipFuzzTransformer { diff --git a/test/fixtures/wpt/streams/transform-streams/patched-global.any.js b/test/fixtures/wpt/streams/transform-streams/patched-global.any.js index 2d04e3b948b324..cc111eda452f0f 100644 --- a/test/fixtures/wpt/streams/transform-streams/patched-global.any.js +++ b/test/fixtures/wpt/streams/transform-streams/patched-global.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; // Tests which patch the global environment are kept separate to avoid diff --git a/test/fixtures/wpt/streams/transform-streams/properties.any.js b/test/fixtures/wpt/streams/transform-streams/properties.any.js index 02981b8bc76a5f..dbfd1aa372b907 100644 --- a/test/fixtures/wpt/streams/transform-streams/properties.any.js +++ b/test/fixtures/wpt/streams/transform-streams/properties.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; const transformerMethods = { diff --git a/test/fixtures/wpt/streams/transform-streams/reentrant-strategies.any.js b/test/fixtures/wpt/streams/transform-streams/reentrant-strategies.any.js index fc2f91886659f6..a6d459655856a7 100644 --- a/test/fixtures/wpt/streams/transform-streams/reentrant-strategies.any.js +++ b/test/fixtures/wpt/streams/transform-streams/reentrant-strategies.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/recording-streams.js // META: script=../resources/rs-utils.js // META: script=../resources/test-utils.js @@ -314,6 +314,10 @@ promise_test(t => { // call to TransformStreamDefaultSink. return delay(0).then(() => { controller.enqueue('a'); + return reader.read(); + }).then(({ value, done }) => { + assert_false(done, 'done should be false'); + assert_equals(value, 'a', 'value should be correct'); return Promise.all([promise_rejects_exactly(t, error1, reader.read(), 'read() should reject'), abortPromise]); }); }, 'writer.abort() inside size() should work'); diff --git a/test/fixtures/wpt/streams/transform-streams/strategies.any.js b/test/fixtures/wpt/streams/transform-streams/strategies.any.js index 94055ad99dc94b..57e113e668ce24 100644 --- a/test/fixtures/wpt/streams/transform-streams/strategies.any.js +++ b/test/fixtures/wpt/streams/transform-streams/strategies.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/recording-streams.js // META: script=../resources/test-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/transform-streams/terminate.any.js b/test/fixtures/wpt/streams/transform-streams/terminate.any.js index 670006366db2af..a959e70fe69339 100644 --- a/test/fixtures/wpt/streams/transform-streams/terminate.any.js +++ b/test/fixtures/wpt/streams/transform-streams/terminate.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/recording-streams.js // META: script=../resources/test-utils.js 'use strict'; diff --git a/test/fixtures/wpt/streams/writable-streams/aborting.any.js b/test/fixtures/wpt/streams/writable-streams/aborting.any.js index e016cd191b876f..9171dbe158f00c 100644 --- a/test/fixtures/wpt/streams/writable-streams/aborting.any.js +++ b/test/fixtures/wpt/streams/writable-streams/aborting.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/streams/writable-streams/bad-strategies.any.js b/test/fixtures/wpt/streams/writable-streams/bad-strategies.any.js index 63fa443065ee41..a1ef0791168f99 100644 --- a/test/fixtures/wpt/streams/writable-streams/bad-strategies.any.js +++ b/test/fixtures/wpt/streams/writable-streams/bad-strategies.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; const error1 = new Error('a unique string'); diff --git a/test/fixtures/wpt/streams/writable-streams/bad-underlying-sinks.any.js b/test/fixtures/wpt/streams/writable-streams/bad-underlying-sinks.any.js index d0b3467978ea05..3c434ffe60ccb9 100644 --- a/test/fixtures/wpt/streams/writable-streams/bad-underlying-sinks.any.js +++ b/test/fixtures/wpt/streams/writable-streams/bad-underlying-sinks.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/streams/writable-streams/byte-length-queuing-strategy.any.js b/test/fixtures/wpt/streams/writable-streams/byte-length-queuing-strategy.any.js index ce1962e8917f32..eed86ee7004ea1 100644 --- a/test/fixtures/wpt/streams/writable-streams/byte-length-queuing-strategy.any.js +++ b/test/fixtures/wpt/streams/writable-streams/byte-length-queuing-strategy.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; promise_test(t => { diff --git a/test/fixtures/wpt/streams/writable-streams/close.any.js b/test/fixtures/wpt/streams/writable-streams/close.any.js index 88855a92efd550..45261e7ca7e01d 100644 --- a/test/fixtures/wpt/streams/writable-streams/close.any.js +++ b/test/fixtures/wpt/streams/writable-streams/close.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/streams/writable-streams/constructor.any.js b/test/fixtures/wpt/streams/writable-streams/constructor.any.js index eaac90e48b8f86..0abc7ef545ea0b 100644 --- a/test/fixtures/wpt/streams/writable-streams/constructor.any.js +++ b/test/fixtures/wpt/streams/writable-streams/constructor.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; const error1 = new Error('error1'); diff --git a/test/fixtures/wpt/streams/writable-streams/count-queuing-strategy.any.js b/test/fixtures/wpt/streams/writable-streams/count-queuing-strategy.any.js index 064e16e81506f1..8211757530d323 100644 --- a/test/fixtures/wpt/streams/writable-streams/count-queuing-strategy.any.js +++ b/test/fixtures/wpt/streams/writable-streams/count-queuing-strategy.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; test(() => { diff --git a/test/fixtures/wpt/streams/writable-streams/error.any.js b/test/fixtures/wpt/streams/writable-streams/error.any.js index faf3fdd9521430..d08c8a54863bb9 100644 --- a/test/fixtures/wpt/streams/writable-streams/error.any.js +++ b/test/fixtures/wpt/streams/writable-streams/error.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; const error1 = new Error('error1'); diff --git a/test/fixtures/wpt/streams/writable-streams/floating-point-total-queue-size.any.js b/test/fixtures/wpt/streams/writable-streams/floating-point-total-queue-size.any.js index bd34cc53a69579..20a14fc19a51e0 100644 --- a/test/fixtures/wpt/streams/writable-streams/floating-point-total-queue-size.any.js +++ b/test/fixtures/wpt/streams/writable-streams/floating-point-total-queue-size.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; // Due to the limitations of floating-point precision, the calculation of desiredSize sometimes gives different answers diff --git a/test/fixtures/wpt/streams/writable-streams/general.any.js b/test/fixtures/wpt/streams/writable-streams/general.any.js index cede7fd0845b74..48f8eeb89e41ee 100644 --- a/test/fixtures/wpt/streams/writable-streams/general.any.js +++ b/test/fixtures/wpt/streams/writable-streams/general.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; test(() => { diff --git a/test/fixtures/wpt/streams/writable-streams/properties.any.js b/test/fixtures/wpt/streams/writable-streams/properties.any.js index c95bd7d0c080ba..ae0549f0871b48 100644 --- a/test/fixtures/wpt/streams/writable-streams/properties.any.js +++ b/test/fixtures/wpt/streams/writable-streams/properties.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm 'use strict'; const sinkMethods = { diff --git a/test/fixtures/wpt/streams/writable-streams/reentrant-strategy.any.js b/test/fixtures/wpt/streams/writable-streams/reentrant-strategy.any.js index eb05cc068043ea..18ce9e84759a11 100644 --- a/test/fixtures/wpt/streams/writable-streams/reentrant-strategy.any.js +++ b/test/fixtures/wpt/streams/writable-streams/reentrant-strategy.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/streams/writable-streams/start.any.js b/test/fixtures/wpt/streams/writable-streams/start.any.js index 82d869430dd700..17972b568ceb24 100644 --- a/test/fixtures/wpt/streams/writable-streams/start.any.js +++ b/test/fixtures/wpt/streams/writable-streams/start.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/streams/writable-streams/write.any.js b/test/fixtures/wpt/streams/writable-streams/write.any.js index f0246f6cad39fd..20a2885bf3512a 100644 --- a/test/fixtures/wpt/streams/writable-streams/write.any.js +++ b/test/fixtures/wpt/streams/writable-streams/write.any.js @@ -1,4 +1,4 @@ -// META: global=window,worker +// META: global=window,worker,shadowrealm // META: script=../resources/test-utils.js // META: script=../resources/recording-streams.js 'use strict'; diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json index dec1aeb4b049d2..ff764aae93b42f 100644 --- a/test/fixtures/wpt/versions.json +++ b/test/fixtures/wpt/versions.json @@ -64,7 +64,7 @@ "path": "resources" }, "streams": { - "commit": "517e945bbfaf903f37a35c11700eb96662efbdd3", + "commit": "a8872d92b147fc87200eb0c14fe7a4a9e7cd4f73", "path": "streams" }, "url": { diff --git a/test/parallel/test-runner-force-exit-failure.js b/test/parallel/test-runner-force-exit-failure.js new file mode 100644 index 00000000000000..1fff8f30d7e038 --- /dev/null +++ b/test/parallel/test-runner-force-exit-failure.js @@ -0,0 +1,15 @@ +'use strict'; +require('../common'); +const { match, doesNotMatch, strictEqual } = require('node:assert'); +const { spawnSync } = require('node:child_process'); +const fixtures = require('../common/fixtures'); +const fixture = fixtures.path('test-runner/throws_sync_and_async.js'); +const r = spawnSync(process.execPath, ['--test', '--test-force-exit', fixture]); + +strictEqual(r.status, 1); +strictEqual(r.signal, null); +strictEqual(r.stderr.toString(), ''); + +const stdout = r.stdout.toString(); +match(stdout, /error: 'fails'/); +doesNotMatch(stdout, /this should not have a chance to be thrown/); diff --git a/test/parallel/test-runner-output.mjs b/test/parallel/test-runner-output.mjs index 847b64a1e24dc0..df1067ec04a4e0 100644 --- a/test/parallel/test-runner-output.mjs +++ b/test/parallel/test-runner-output.mjs @@ -105,6 +105,7 @@ const tests = [ { name: 'test-runner/output/global-hooks-with-no-tests.js' }, { name: 'test-runner/output/before-and-after-each-too-many-listeners.js' }, { name: 'test-runner/output/before-and-after-each-with-timeout-too-many-listeners.js' }, + { name: 'test-runner/output/force_exit.js', transform: specTransform }, { name: 'test-runner/output/global_after_should_fail_the_test.js' }, { name: 'test-runner/output/no_refs.js' }, { name: 'test-runner/output/no_tests.js' }, @@ -114,6 +115,7 @@ const tests = [ { name: 'test-runner/output/spec_reporter_successful.js', transform: specTransform }, { name: 'test-runner/output/spec_reporter.js', transform: specTransform }, { name: 'test-runner/output/spec_reporter_cli.js', transform: specTransform }, + { name: 'test-runner/output/source_mapped_locations.mjs' }, process.features.inspector ? { name: 'test-runner/output/lcov_reporter.js', transform: lcovTransform } : false, { name: 'test-runner/output/output.js' }, { name: 'test-runner/output/output_cli.js' }, diff --git a/test/parallel/test-runner-run.mjs b/test/parallel/test-runner-run.mjs index 079fa57f25855f..d6295522f96d95 100644 --- a/test/parallel/test-runner-run.mjs +++ b/test/parallel/test-runner-run.mjs @@ -526,3 +526,21 @@ describe('require(\'node:test\').run', { concurrency: true }, () => { assert.match(stderr, /Warning: node:test run\(\) is being called recursively/); }); }); + +describe('forceExit', () => { + it('throws for non-boolean values', () => { + [Symbol(), {}, 0, 1, '1', Promise.resolve([])].forEach((forceExit) => { + assert.throws(() => run({ forceExit }), { + code: 'ERR_INVALID_ARG_TYPE', + message: /The "options\.forceExit" property must be of type boolean\./ + }); + }); + }); + + it('throws if enabled with watch mode', () => { + assert.throws(() => run({ forceExit: true, watch: true }), { + code: 'ERR_INVALID_ARG_VALUE', + message: /The property 'options\.forceExit' is not supported with watch mode\./ + }); + }); +}); diff --git a/test/parallel/test-webstreams-clone-unref.js b/test/parallel/test-webstreams-clone-unref.js new file mode 100644 index 00000000000000..88a9cebd9c3046 --- /dev/null +++ b/test/parallel/test-webstreams-clone-unref.js @@ -0,0 +1,16 @@ +'use strict'; + +require('../common'); +const { ok } = require('node:assert'); + +// This test verifies that cloned ReadableStream and WritableStream instances +// do not keep the process alive. The test fails if it timesout (it should just +// exit immediately) + +const rs1 = new ReadableStream(); +const ws1 = new WritableStream(); + +const [rs2, ws2] = structuredClone([rs1, ws1], { transfer: [rs1, ws1] }); + +ok(rs2 instanceof ReadableStream); +ok(ws2 instanceof WritableStream); diff --git a/test/parallel/test-whatwg-webstreams-transfer.js b/test/parallel/test-whatwg-webstreams-transfer.js index b5122823e46b3b..cf9b97a5ccd1c4 100644 --- a/test/parallel/test-whatwg-webstreams-transfer.js +++ b/test/parallel/test-whatwg-webstreams-transfer.js @@ -454,12 +454,23 @@ const theData = 'hello'; tracker.verify(); }); + // We create an interval to keep the event loop alive while + // we wait for the stream read to complete. The reason this is needed is because there's + // otherwise nothing to keep the worker thread event loop alive long enough to actually + // complete the read from the stream. Under the covers the ReadableStream uses an + // unref'd MessagePort to communicate with the main thread. Because the MessagePort + // is unref'd, it's existence would not keep the thread alive on its own. There was previously + // a bug where this MessagePort was ref'd which would block the thread and main thread + // from terminating at all unless the stream was consumed/closed. + const i = setInterval(() => {}, 1000); + parentPort.onmessage = tracker.calls(({ data }) => { assert(isReadableStream(data)); const reader = data.getReader(); reader.read().then(tracker.calls((result) => { assert(!result.done); assert(result.value instanceof Uint8Array); + clearInterval(i); })); parentPort.close(); }); diff --git a/test/v8-updates/test-linux-perf-logger.js b/test/v8-updates/test-linux-perf-logger.js index 8b00d332585121..ffea7257bbeae3 100644 --- a/test/v8-updates/test-linux-perf-logger.js +++ b/test/v8-updates/test-linux-perf-logger.js @@ -48,7 +48,7 @@ const testCases = [ }, { title: '--perf-basic-prof compiled', - nodeFlags: ['--perf-basic-prof', '--no-turbo-inlining', '--always-opt'], + nodeFlags: ['--perf-basic-prof', '--no-turbo-inlining', '--always-turbofan'], matches: [ 'test-regex', '~functionOne .+/linux-perf-logger.js', @@ -66,7 +66,7 @@ const testCases = [ }, { title: '--perf-basic-prof-only-functions compiled', - nodeFlags: ['--perf-basic-prof-only-functions', '--no-turbo-inlining', '--always-opt'], + nodeFlags: ['--perf-basic-prof-only-functions', '--no-turbo-inlining', '--always-turbofan'], matches: [ '~functionOne .+/linux-perf-logger.js', '~functionTwo .+/linux-perf-logger.js', diff --git a/test/v8-updates/v8-updates.status b/test/v8-updates/v8-updates.status index 46149f4751ffb5..07ff708ab023dc 100644 --- a/test/v8-updates/v8-updates.status +++ b/test/v8-updates/v8-updates.status @@ -5,6 +5,8 @@ prefix v8-updates # sample-test : PASS,FLAKY [true] # This section applies to all platforms +# https://github.com/nodejs/node/issues/50079 +test-linux-perf: SKIP [$system==win32] diff --git a/test/wasi/c/create_symlink.c b/test/wasi/c/create_symlink.c index 319b10c6909781..bf9d804753c1dc 100644 --- a/test/wasi/c/create_symlink.c +++ b/test/wasi/c/create_symlink.c @@ -11,7 +11,7 @@ int main() { assert(0 == symlink(target, linkpath)); assert(readlink(linkpath, readlink_result, result_size) == - strlen(target) + 1); + strlen(target)); assert(0 == strcmp(readlink_result, target)); FILE* file = fopen(linkpath, "r"); diff --git a/test/wasi/wasm/create_symlink.wasm b/test/wasi/wasm/create_symlink.wasm index 64e120cd5a617b..be824359be6372 100755 Binary files a/test/wasi/wasm/create_symlink.wasm and b/test/wasi/wasm/create_symlink.wasm differ diff --git a/test/wpt/status/streams.json b/test/wpt/status/streams.json index 3b6e0ce6429f9d..8d6a4c6d2fe27b 100644 --- a/test/wpt/status/streams.json +++ b/test/wpt/status/streams.json @@ -59,5 +59,12 @@ }, "readable-streams/read-task-handling.window.js": { "skip": "Browser-specific test" + }, + "transform-streams/cancel.any.js": { + "fail": { + "expected": [ + "readable.cancel() and a parallel writable.close() should reject if a transformer.cancel() calls controller.error()" + ] + } } } diff --git a/tools/lint-md/lint-md.mjs b/tools/lint-md/lint-md.mjs index 3f433622517c4c..2130891fe75d43 100644 --- a/tools/lint-md/lint-md.mjs +++ b/tools/lint-md/lint-md.mjs @@ -818,7 +818,7 @@ function isUint8Array$1(value) { const emptyOptions$2 = {}; function toString(value, options) { - const settings = options || emptyOptions$2; + const settings = emptyOptions$2; const includeImageAlt = typeof settings.includeImageAlt === 'boolean' ? settings.includeImageAlt @@ -3439,59 +3439,36 @@ function resolveAllAttention(events, context) { let nextEvents; let offset; while (++index < events.length) { - if ( - events[index][0] === 'enter' && - events[index][1].type === 'attentionSequence' && - events[index][1]._close - ) { + if (events[index][0] === 'enter' && events[index][1].type === 'attentionSequence' && events[index][1]._close) { open = index; while (open--) { - if ( - events[open][0] === 'exit' && - events[open][1].type === 'attentionSequence' && - events[open][1]._open && - context.sliceSerialize(events[open][1]).charCodeAt(0) === - context.sliceSerialize(events[index][1]).charCodeAt(0) - ) { - if ( - (events[open][1]._close || events[index][1]._open) && - (events[index][1].end.offset - events[index][1].start.offset) % 3 && - !( - (events[open][1].end.offset - - events[open][1].start.offset + - events[index][1].end.offset - - events[index][1].start.offset) % - 3 - ) - ) { - continue + if (events[open][0] === 'exit' && events[open][1].type === 'attentionSequence' && events[open][1]._open && + context.sliceSerialize(events[open][1]).charCodeAt(0) === context.sliceSerialize(events[index][1]).charCodeAt(0)) { + if ((events[open][1]._close || events[index][1]._open) && (events[index][1].end.offset - events[index][1].start.offset) % 3 && !((events[open][1].end.offset - events[open][1].start.offset + events[index][1].end.offset - events[index][1].start.offset) % 3)) { + continue; } - use = - events[open][1].end.offset - events[open][1].start.offset > 1 && - events[index][1].end.offset - events[index][1].start.offset > 1 - ? 2 - : 1; + use = events[open][1].end.offset - events[open][1].start.offset > 1 && events[index][1].end.offset - events[index][1].start.offset > 1 ? 2 : 1; const start = Object.assign({}, events[open][1].end); const end = Object.assign({}, events[index][1].start); movePoint(start, -use); movePoint(end, use); openingSequence = { - type: use > 1 ? 'strongSequence' : 'emphasisSequence', + type: use > 1 ? "strongSequence" : "emphasisSequence", start, end: Object.assign({}, events[open][1].end) }; closingSequence = { - type: use > 1 ? 'strongSequence' : 'emphasisSequence', + type: use > 1 ? "strongSequence" : "emphasisSequence", start: Object.assign({}, events[index][1].start), end }; text = { - type: use > 1 ? 'strongText' : 'emphasisText', + type: use > 1 ? "strongText" : "emphasisText", start: Object.assign({}, events[open][1].end), end: Object.assign({}, events[index][1].start) }; group = { - type: use > 1 ? 'strong' : 'emphasis', + type: use > 1 ? "strong" : "emphasis", start: Object.assign({}, openingSequence.start), end: Object.assign({}, closingSequence.end) }; @@ -3499,43 +3476,20 @@ function resolveAllAttention(events, context) { events[index][1].start = Object.assign({}, closingSequence.end); nextEvents = []; if (events[open][1].end.offset - events[open][1].start.offset) { - nextEvents = push(nextEvents, [ - ['enter', events[open][1], context], - ['exit', events[open][1], context] - ]); + nextEvents = push(nextEvents, [['enter', events[open][1], context], ['exit', events[open][1], context]]); } - nextEvents = push(nextEvents, [ - ['enter', group, context], - ['enter', openingSequence, context], - ['exit', openingSequence, context], - ['enter', text, context] - ]); - nextEvents = push( - nextEvents, - resolveAll( - context.parser.constructs.insideSpan.null, - events.slice(open + 1, index), - context - ) - ); - nextEvents = push(nextEvents, [ - ['exit', text, context], - ['enter', closingSequence, context], - ['exit', closingSequence, context], - ['exit', group, context] - ]); + nextEvents = push(nextEvents, [['enter', group, context], ['enter', openingSequence, context], ['exit', openingSequence, context], ['enter', text, context]]); + nextEvents = push(nextEvents, resolveAll(context.parser.constructs.insideSpan.null, events.slice(open + 1, index), context)); + nextEvents = push(nextEvents, [['exit', text, context], ['enter', closingSequence, context], ['exit', closingSequence, context], ['exit', group, context]]); if (events[index][1].end.offset - events[index][1].start.offset) { offset = 2; - nextEvents = push(nextEvents, [ - ['enter', events[index][1], context], - ['exit', events[index][1], context] - ]); + nextEvents = push(nextEvents, [['enter', events[index][1], context], ['exit', events[index][1], context]]); } else { offset = 0; } splice(events, open - 1, index - open + 3, nextEvents); index = open + nextEvents.length - offset - 2; - break + break; } } } @@ -3546,33 +3500,31 @@ function resolveAllAttention(events, context) { events[index][1].type = 'data'; } } - return events + return events; } function tokenizeAttention(effects, ok) { const attentionMarkers = this.parser.constructs.attentionMarkers.null; const previous = this.previous; const before = classifyCharacter(previous); let marker; - return start + return start; function start(code) { marker = code; effects.enter('attentionSequence'); - return inside(code) + return inside(code); } function inside(code) { if (code === marker) { effects.consume(code); - return inside + return inside; } const token = effects.exit('attentionSequence'); const after = classifyCharacter(code); - const open = - !after || (after === 2 && before) || attentionMarkers.includes(code); - const close = - !before || (before === 2 && after) || attentionMarkers.includes(previous); + const open = !after || after === 2 && before || attentionMarkers.includes(code); + const close = !before || before === 2 && after || attentionMarkers.includes(previous); token._open = Boolean(marker === 42 ? open : open && (before || !close)); token._close = Boolean(marker === 42 ? close : close && (after || !open)); - return ok(code) + return ok(code); } } function movePoint(point, offset) { @@ -3587,97 +3539,97 @@ const autolink = { }; function tokenizeAutolink(effects, ok, nok) { let size = 0; - return start + return start; function start(code) { - effects.enter('autolink'); - effects.enter('autolinkMarker'); + effects.enter("autolink"); + effects.enter("autolinkMarker"); effects.consume(code); - effects.exit('autolinkMarker'); - effects.enter('autolinkProtocol'); - return open + effects.exit("autolinkMarker"); + effects.enter("autolinkProtocol"); + return open; } function open(code) { if (asciiAlpha(code)) { effects.consume(code); - return schemeOrEmailAtext + return schemeOrEmailAtext; } - return emailAtext(code) + if (code === 64) { + return nok(code); + } + return emailAtext(code); } function schemeOrEmailAtext(code) { if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { size = 1; - return schemeInsideOrEmailAtext(code) + return schemeInsideOrEmailAtext(code); } - return emailAtext(code) + return emailAtext(code); } function schemeInsideOrEmailAtext(code) { if (code === 58) { effects.consume(code); size = 0; - return urlInside + return urlInside; } - if ( - (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && - size++ < 32 - ) { + if ((code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && size++ < 32) { effects.consume(code); - return schemeInsideOrEmailAtext + return schemeInsideOrEmailAtext; } size = 0; - return emailAtext(code) + return emailAtext(code); } function urlInside(code) { if (code === 62) { - effects.exit('autolinkProtocol'); - effects.enter('autolinkMarker'); + effects.exit("autolinkProtocol"); + effects.enter("autolinkMarker"); effects.consume(code); - effects.exit('autolinkMarker'); - effects.exit('autolink'); - return ok + effects.exit("autolinkMarker"); + effects.exit("autolink"); + return ok; } if (code === null || code === 32 || code === 60 || asciiControl(code)) { - return nok(code) + return nok(code); } effects.consume(code); - return urlInside + return urlInside; } function emailAtext(code) { if (code === 64) { effects.consume(code); - return emailAtSignOrDot + return emailAtSignOrDot; } if (asciiAtext(code)) { effects.consume(code); - return emailAtext + return emailAtext; } - return nok(code) + return nok(code); } function emailAtSignOrDot(code) { - return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code); } function emailLabel(code) { if (code === 46) { effects.consume(code); size = 0; - return emailAtSignOrDot + return emailAtSignOrDot; } if (code === 62) { - effects.exit('autolinkProtocol').type = 'autolinkEmail'; - effects.enter('autolinkMarker'); + effects.exit("autolinkProtocol").type = "autolinkEmail"; + effects.enter("autolinkMarker"); effects.consume(code); - effects.exit('autolinkMarker'); - effects.exit('autolink'); - return ok + effects.exit("autolinkMarker"); + effects.exit("autolink"); + return ok; } - return emailValue(code) + return emailValue(code); } function emailValue(code) { if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { const next = code === 45 ? emailValue : emailLabel; effects.consume(code); - return next + return next; } - return nok(code) + return nok(code); } } @@ -3686,14 +3638,12 @@ const blankLine = { partial: true }; function tokenizeBlankLine(effects, ok, nok) { - return start + return start; function start(code) { - return markdownSpace(code) - ? factorySpace(effects, after, 'linePrefix')(code) - : after(code) + return markdownSpace(code) ? factorySpace(effects, after, "linePrefix")(code) : after(code); } function after(code) { - return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + return code === null || markdownLineEnding(code) ? ok(code) : nok(code); } } @@ -3707,58 +3657,51 @@ const blockQuote = { }; function tokenizeBlockQuoteStart(effects, ok, nok) { const self = this; - return start + return start; function start(code) { if (code === 62) { const state = self.containerState; if (!state.open) { - effects.enter('blockQuote', { + effects.enter("blockQuote", { _container: true }); state.open = true; } - effects.enter('blockQuotePrefix'); - effects.enter('blockQuoteMarker'); + effects.enter("blockQuotePrefix"); + effects.enter("blockQuoteMarker"); effects.consume(code); - effects.exit('blockQuoteMarker'); - return after + effects.exit("blockQuoteMarker"); + return after; } - return nok(code) + return nok(code); } function after(code) { if (markdownSpace(code)) { - effects.enter('blockQuotePrefixWhitespace'); + effects.enter("blockQuotePrefixWhitespace"); effects.consume(code); - effects.exit('blockQuotePrefixWhitespace'); - effects.exit('blockQuotePrefix'); - return ok + effects.exit("blockQuotePrefixWhitespace"); + effects.exit("blockQuotePrefix"); + return ok; } - effects.exit('blockQuotePrefix'); - return ok(code) + effects.exit("blockQuotePrefix"); + return ok(code); } } function tokenizeBlockQuoteContinuation(effects, ok, nok) { const self = this; - return contStart + return contStart; function contStart(code) { if (markdownSpace(code)) { - return factorySpace( - effects, - contBefore, - 'linePrefix', - self.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 - )(code) + return factorySpace(effects, contBefore, "linePrefix", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4)(code); } - return contBefore(code) + return contBefore(code); } function contBefore(code) { - return effects.attempt(blockQuote, ok, nok)(code) + return effects.attempt(blockQuote, ok, nok)(code); } } function exit$1(effects) { - effects.exit('blockQuote'); + effects.exit("blockQuote"); } const characterEscape = { @@ -3766,23 +3709,23 @@ const characterEscape = { tokenize: tokenizeCharacterEscape }; function tokenizeCharacterEscape(effects, ok, nok) { - return start + return start; function start(code) { - effects.enter('characterEscape'); - effects.enter('escapeMarker'); + effects.enter("characterEscape"); + effects.enter("escapeMarker"); effects.consume(code); - effects.exit('escapeMarker'); - return inside + effects.exit("escapeMarker"); + return inside; } function inside(code) { if (asciiPunctuation(code)) { - effects.enter('characterEscapeValue'); + effects.enter("characterEscapeValue"); effects.consume(code); - effects.exit('characterEscapeValue'); - effects.exit('characterEscape'); - return ok + effects.exit("characterEscapeValue"); + effects.exit("characterEscape"); + return ok; } - return nok(code) + return nok(code); } } @@ -3795,61 +3738,58 @@ function tokenizeCharacterReference(effects, ok, nok) { let size = 0; let max; let test; - return start + return start; function start(code) { - effects.enter('characterReference'); - effects.enter('characterReferenceMarker'); + effects.enter("characterReference"); + effects.enter("characterReferenceMarker"); effects.consume(code); - effects.exit('characterReferenceMarker'); - return open + effects.exit("characterReferenceMarker"); + return open; } function open(code) { if (code === 35) { - effects.enter('characterReferenceMarkerNumeric'); + effects.enter("characterReferenceMarkerNumeric"); effects.consume(code); - effects.exit('characterReferenceMarkerNumeric'); - return numeric + effects.exit("characterReferenceMarkerNumeric"); + return numeric; } - effects.enter('characterReferenceValue'); + effects.enter("characterReferenceValue"); max = 31; test = asciiAlphanumeric; - return value(code) + return value(code); } function numeric(code) { if (code === 88 || code === 120) { - effects.enter('characterReferenceMarkerHexadecimal'); + effects.enter("characterReferenceMarkerHexadecimal"); effects.consume(code); - effects.exit('characterReferenceMarkerHexadecimal'); - effects.enter('characterReferenceValue'); + effects.exit("characterReferenceMarkerHexadecimal"); + effects.enter("characterReferenceValue"); max = 6; test = asciiHexDigit; - return value + return value; } - effects.enter('characterReferenceValue'); + effects.enter("characterReferenceValue"); max = 7; test = asciiDigit; - return value(code) + return value(code); } function value(code) { if (code === 59 && size) { - const token = effects.exit('characterReferenceValue'); - if ( - test === asciiAlphanumeric && - !decodeNamedCharacterReference(self.sliceSerialize(token)) - ) { - return nok(code) + const token = effects.exit("characterReferenceValue"); + if (test === asciiAlphanumeric && !decodeNamedCharacterReference(self.sliceSerialize(token))) { + return nok(code); } - effects.enter('characterReferenceMarker'); + effects.enter("characterReferenceMarker"); effects.consume(code); - effects.exit('characterReferenceMarker'); - effects.exit('characterReference'); - return ok + effects.exit("characterReferenceMarker"); + effects.exit("characterReference"); + return ok; } if (test(code) && size++ < max) { effects.consume(code); - return value + return value; } - return nok(code) + return nok(code); } } @@ -3871,192 +3811,167 @@ function tokenizeCodeFenced(effects, ok, nok) { let initialPrefix = 0; let sizeOpen = 0; let marker; - return start + return start; function start(code) { - return beforeSequenceOpen(code) + return beforeSequenceOpen(code); } function beforeSequenceOpen(code) { const tail = self.events[self.events.length - 1]; - initialPrefix = - tail && tail[1].type === 'linePrefix' - ? tail[2].sliceSerialize(tail[1], true).length - : 0; + initialPrefix = tail && tail[1].type === "linePrefix" ? tail[2].sliceSerialize(tail[1], true).length : 0; marker = code; - effects.enter('codeFenced'); - effects.enter('codeFencedFence'); - effects.enter('codeFencedFenceSequence'); - return sequenceOpen(code) + effects.enter("codeFenced"); + effects.enter("codeFencedFence"); + effects.enter("codeFencedFenceSequence"); + return sequenceOpen(code); } function sequenceOpen(code) { if (code === marker) { sizeOpen++; effects.consume(code); - return sequenceOpen + return sequenceOpen; } if (sizeOpen < 3) { - return nok(code) + return nok(code); } - effects.exit('codeFencedFenceSequence'); - return markdownSpace(code) - ? factorySpace(effects, infoBefore, 'whitespace')(code) - : infoBefore(code) + effects.exit("codeFencedFenceSequence"); + return markdownSpace(code) ? factorySpace(effects, infoBefore, "whitespace")(code) : infoBefore(code); } function infoBefore(code) { if (code === null || markdownLineEnding(code)) { - effects.exit('codeFencedFence'); - return self.interrupt - ? ok(code) - : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + effects.exit("codeFencedFence"); + return self.interrupt ? ok(code) : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code); } - effects.enter('codeFencedFenceInfo'); - effects.enter('chunkString', { - contentType: 'string' + effects.enter("codeFencedFenceInfo"); + effects.enter("chunkString", { + contentType: "string" }); - return info(code) + return info(code); } function info(code) { if (code === null || markdownLineEnding(code)) { - effects.exit('chunkString'); - effects.exit('codeFencedFenceInfo'); - return infoBefore(code) + effects.exit("chunkString"); + effects.exit("codeFencedFenceInfo"); + return infoBefore(code); } if (markdownSpace(code)) { - effects.exit('chunkString'); - effects.exit('codeFencedFenceInfo'); - return factorySpace(effects, metaBefore, 'whitespace')(code) + effects.exit("chunkString"); + effects.exit("codeFencedFenceInfo"); + return factorySpace(effects, metaBefore, "whitespace")(code); } if (code === 96 && code === marker) { - return nok(code) + return nok(code); } effects.consume(code); - return info + return info; } function metaBefore(code) { if (code === null || markdownLineEnding(code)) { - return infoBefore(code) + return infoBefore(code); } - effects.enter('codeFencedFenceMeta'); - effects.enter('chunkString', { - contentType: 'string' + effects.enter("codeFencedFenceMeta"); + effects.enter("chunkString", { + contentType: "string" }); - return meta(code) + return meta(code); } function meta(code) { if (code === null || markdownLineEnding(code)) { - effects.exit('chunkString'); - effects.exit('codeFencedFenceMeta'); - return infoBefore(code) + effects.exit("chunkString"); + effects.exit("codeFencedFenceMeta"); + return infoBefore(code); } if (code === 96 && code === marker) { - return nok(code) + return nok(code); } effects.consume(code); - return meta + return meta; } function atNonLazyBreak(code) { - return effects.attempt(closeStart, after, contentBefore)(code) + return effects.attempt(closeStart, after, contentBefore)(code); } function contentBefore(code) { - effects.enter('lineEnding'); + effects.enter("lineEnding"); effects.consume(code); - effects.exit('lineEnding'); - return contentStart + effects.exit("lineEnding"); + return contentStart; } function contentStart(code) { - return initialPrefix > 0 && markdownSpace(code) - ? factorySpace( - effects, - beforeContentChunk, - 'linePrefix', - initialPrefix + 1 - )(code) - : beforeContentChunk(code) + return initialPrefix > 0 && markdownSpace(code) ? factorySpace(effects, beforeContentChunk, "linePrefix", initialPrefix + 1)(code) : beforeContentChunk(code); } function beforeContentChunk(code) { if (code === null || markdownLineEnding(code)) { - return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code); } - effects.enter('codeFlowValue'); - return contentChunk(code) + effects.enter("codeFlowValue"); + return contentChunk(code); } function contentChunk(code) { if (code === null || markdownLineEnding(code)) { - effects.exit('codeFlowValue'); - return beforeContentChunk(code) + effects.exit("codeFlowValue"); + return beforeContentChunk(code); } effects.consume(code); - return contentChunk + return contentChunk; } function after(code) { - effects.exit('codeFenced'); - return ok(code) + effects.exit("codeFenced"); + return ok(code); } function tokenizeCloseStart(effects, ok, nok) { let size = 0; - return startBefore + return startBefore; function startBefore(code) { - effects.enter('lineEnding'); + effects.enter("lineEnding"); effects.consume(code); - effects.exit('lineEnding'); - return start + effects.exit("lineEnding"); + return start; } function start(code) { - effects.enter('codeFencedFence'); - return markdownSpace(code) - ? factorySpace( - effects, - beforeSequenceClose, - 'linePrefix', - self.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 - )(code) - : beforeSequenceClose(code) + effects.enter("codeFencedFence"); + return markdownSpace(code) ? factorySpace(effects, beforeSequenceClose, "linePrefix", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4)(code) : beforeSequenceClose(code); } function beforeSequenceClose(code) { if (code === marker) { - effects.enter('codeFencedFenceSequence'); - return sequenceClose(code) + effects.enter("codeFencedFenceSequence"); + return sequenceClose(code); } - return nok(code) + return nok(code); } function sequenceClose(code) { if (code === marker) { size++; effects.consume(code); - return sequenceClose + return sequenceClose; } if (size >= sizeOpen) { - effects.exit('codeFencedFenceSequence'); - return markdownSpace(code) - ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) - : sequenceCloseAfter(code) + effects.exit("codeFencedFenceSequence"); + return markdownSpace(code) ? factorySpace(effects, sequenceCloseAfter, "whitespace")(code) : sequenceCloseAfter(code); } - return nok(code) + return nok(code); } function sequenceCloseAfter(code) { if (code === null || markdownLineEnding(code)) { - effects.exit('codeFencedFence'); - return ok(code) + effects.exit("codeFencedFence"); + return ok(code); } - return nok(code) + return nok(code); } } } function tokenizeNonLazyContinuation(effects, ok, nok) { const self = this; - return start + return start; function start(code) { if (code === null) { - return nok(code) + return nok(code); } - effects.enter('lineEnding'); + effects.enter("lineEnding"); effects.consume(code); - effects.exit('lineEnding'); - return lineStart + effects.exit("lineEnding"); + return lineStart; } function lineStart(code) { - return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + return self.parser.lazy[self.now().line] ? nok(code) : ok(code); } } @@ -4070,66 +3985,56 @@ const furtherStart = { }; function tokenizeCodeIndented(effects, ok, nok) { const self = this; - return start + return start; function start(code) { - effects.enter('codeIndented'); - return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + effects.enter("codeIndented"); + return factorySpace(effects, afterPrefix, "linePrefix", 4 + 1)(code); } function afterPrefix(code) { const tail = self.events[self.events.length - 1]; - return tail && - tail[1].type === 'linePrefix' && - tail[2].sliceSerialize(tail[1], true).length >= 4 - ? atBreak(code) - : nok(code) + return tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? atBreak(code) : nok(code); } function atBreak(code) { if (code === null) { - return after(code) + return after(code); } if (markdownLineEnding(code)) { - return effects.attempt(furtherStart, atBreak, after)(code) + return effects.attempt(furtherStart, atBreak, after)(code); } - effects.enter('codeFlowValue'); - return inside(code) + effects.enter("codeFlowValue"); + return inside(code); } function inside(code) { if (code === null || markdownLineEnding(code)) { - effects.exit('codeFlowValue'); - return atBreak(code) + effects.exit("codeFlowValue"); + return atBreak(code); } effects.consume(code); - return inside + return inside; } function after(code) { - effects.exit('codeIndented'); - return ok(code) + effects.exit("codeIndented"); + return ok(code); } } function tokenizeFurtherStart(effects, ok, nok) { const self = this; - return furtherStart + return furtherStart; function furtherStart(code) { if (self.parser.lazy[self.now().line]) { - return nok(code) + return nok(code); } if (markdownLineEnding(code)) { - effects.enter('lineEnding'); + effects.enter("lineEnding"); effects.consume(code); - effects.exit('lineEnding'); - return furtherStart + effects.exit("lineEnding"); + return furtherStart; } - return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + return factorySpace(effects, afterPrefix, "linePrefix", 4 + 1)(code); } function afterPrefix(code) { const tail = self.events[self.events.length - 1]; - return tail && - tail[1].type === 'linePrefix' && - tail[2].sliceSerialize(tail[1], true).length >= 4 - ? ok(code) - : markdownLineEnding(code) - ? furtherStart(code) - : nok(code) + return tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? ok(code) : markdownLineEnding(code) ? furtherStart(code) : nok(code); } } @@ -4144,20 +4049,15 @@ function resolveCodeText(events) { let headEnterIndex = 3; let index; let enter; - if ( - (events[headEnterIndex][1].type === 'lineEnding' || - events[headEnterIndex][1].type === 'space') && - (events[tailExitIndex][1].type === 'lineEnding' || - events[tailExitIndex][1].type === 'space') - ) { + if ((events[headEnterIndex][1].type === "lineEnding" || events[headEnterIndex][1].type === 'space') && (events[tailExitIndex][1].type === "lineEnding" || events[tailExitIndex][1].type === 'space')) { index = headEnterIndex; while (++index < tailExitIndex) { - if (events[index][1].type === 'codeTextData') { - events[headEnterIndex][1].type = 'codeTextPadding'; - events[tailExitIndex][1].type = 'codeTextPadding'; + if (events[index][1].type === "codeTextData") { + events[headEnterIndex][1].type = "codeTextPadding"; + events[tailExitIndex][1].type = "codeTextPadding"; headEnterIndex += 2; tailExitIndex -= 2; - break + break; } } } @@ -4165,14 +4065,11 @@ function resolveCodeText(events) { tailExitIndex++; while (++index <= tailExitIndex) { if (enter === undefined) { - if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + if (index !== tailExitIndex && events[index][1].type !== "lineEnding") { enter = index; } - } else if ( - index === tailExitIndex || - events[index][1].type === 'lineEnding' - ) { - events[enter][1].type = 'codeTextData'; + } else if (index === tailExitIndex || events[index][1].type === "lineEnding") { + events[enter][1].type = "codeTextData"; if (index !== enter + 2) { events[enter][1].end = events[index - 1][1].end; events.splice(enter + 2, index - enter - 2); @@ -4182,83 +4079,75 @@ function resolveCodeText(events) { enter = undefined; } } - return events + return events; } function previous$1(code) { - return ( - code !== 96 || - this.events[this.events.length - 1][1].type === 'characterEscape' - ) + return code !== 96 || this.events[this.events.length - 1][1].type === "characterEscape"; } function tokenizeCodeText(effects, ok, nok) { let sizeOpen = 0; let size; let token; - return start + return start; function start(code) { - effects.enter('codeText'); - effects.enter('codeTextSequence'); - return sequenceOpen(code) + effects.enter("codeText"); + effects.enter("codeTextSequence"); + return sequenceOpen(code); } function sequenceOpen(code) { if (code === 96) { effects.consume(code); sizeOpen++; - return sequenceOpen + return sequenceOpen; } - effects.exit('codeTextSequence'); - return between(code) + effects.exit("codeTextSequence"); + return between(code); } function between(code) { if (code === null) { - return nok(code) + return nok(code); } if (code === 32) { effects.enter('space'); effects.consume(code); effects.exit('space'); - return between + return between; } if (code === 96) { - token = effects.enter('codeTextSequence'); + token = effects.enter("codeTextSequence"); size = 0; - return sequenceClose(code) + return sequenceClose(code); } if (markdownLineEnding(code)) { - effects.enter('lineEnding'); + effects.enter("lineEnding"); effects.consume(code); - effects.exit('lineEnding'); - return between + effects.exit("lineEnding"); + return between; } - effects.enter('codeTextData'); - return data(code) + effects.enter("codeTextData"); + return data(code); } function data(code) { - if ( - code === null || - code === 32 || - code === 96 || - markdownLineEnding(code) - ) { - effects.exit('codeTextData'); - return between(code) + if (code === null || code === 32 || code === 96 || markdownLineEnding(code)) { + effects.exit("codeTextData"); + return between(code); } effects.consume(code); - return data + return data; } function sequenceClose(code) { if (code === 96) { effects.consume(code); size++; - return sequenceClose + return sequenceClose; } if (size === sizeOpen) { - effects.exit('codeTextSequence'); - effects.exit('codeText'); - return ok(code) + effects.exit("codeTextSequence"); + effects.exit("codeText"); + return ok(code); } - token.type = 'codeTextData'; - return data(code) + token.type = "codeTextData"; + return data(code); } } @@ -4493,72 +4382,63 @@ const continuationConstruct = { }; function resolveContent(events) { subtokenize(events); - return events + return events; } function tokenizeContent(effects, ok) { let previous; - return chunkStart + return chunkStart; function chunkStart(code) { - effects.enter('content'); - previous = effects.enter('chunkContent', { - contentType: 'content' + effects.enter("content"); + previous = effects.enter("chunkContent", { + contentType: "content" }); - return chunkInside(code) + return chunkInside(code); } function chunkInside(code) { if (code === null) { - return contentEnd(code) + return contentEnd(code); } if (markdownLineEnding(code)) { - return effects.check( - continuationConstruct, - contentContinue, - contentEnd - )(code) + return effects.check(continuationConstruct, contentContinue, contentEnd)(code); } effects.consume(code); - return chunkInside + return chunkInside; } function contentEnd(code) { - effects.exit('chunkContent'); - effects.exit('content'); - return ok(code) + effects.exit("chunkContent"); + effects.exit("content"); + return ok(code); } function contentContinue(code) { effects.consume(code); - effects.exit('chunkContent'); - previous.next = effects.enter('chunkContent', { - contentType: 'content', + effects.exit("chunkContent"); + previous.next = effects.enter("chunkContent", { + contentType: "content", previous }); previous = previous.next; - return chunkInside + return chunkInside; } } function tokenizeContinuation(effects, ok, nok) { const self = this; - return startLookahead + return startLookahead; function startLookahead(code) { - effects.exit('chunkContent'); - effects.enter('lineEnding'); + effects.exit("chunkContent"); + effects.enter("lineEnding"); effects.consume(code); - effects.exit('lineEnding'); - return factorySpace(effects, prefixed, 'linePrefix') + effects.exit("lineEnding"); + return factorySpace(effects, prefixed, "linePrefix"); } function prefixed(code) { if (code === null || markdownLineEnding(code)) { - return nok(code) + return nok(code); } const tail = self.events[self.events.length - 1]; - if ( - !self.parser.constructs.disable.null.includes('codeIndented') && - tail && - tail[1].type === 'linePrefix' && - tail[2].sliceSerialize(tail[1], true).length >= 4 - ) { - return ok(code) + if (!self.parser.constructs.disable.null.includes('codeIndented') && tail && tail[1].type === "linePrefix" && tail[2].sliceSerialize(tail[1], true).length >= 4) { + return ok(code); } - return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code); } } @@ -4829,92 +4709,60 @@ const titleBefore = { function tokenizeDefinition(effects, ok, nok) { const self = this; let identifier; - return start + return start; function start(code) { - effects.enter('definition'); - return before(code) + effects.enter("definition"); + return before(code); } function before(code) { - return factoryLabel.call( - self, - effects, - labelAfter, - nok, - 'definitionLabel', - 'definitionLabelMarker', - 'definitionLabelString' - )(code) + return factoryLabel.call(self, effects, labelAfter, + nok, "definitionLabel", "definitionLabelMarker", "definitionLabelString")(code); } function labelAfter(code) { - identifier = normalizeIdentifier( - self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) - ); + identifier = normalizeIdentifier(self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1)); if (code === 58) { - effects.enter('definitionMarker'); + effects.enter("definitionMarker"); effects.consume(code); - effects.exit('definitionMarker'); - return markerAfter + effects.exit("definitionMarker"); + return markerAfter; } - return nok(code) + return nok(code); } function markerAfter(code) { - return markdownLineEndingOrSpace(code) - ? factoryWhitespace(effects, destinationBefore)(code) - : destinationBefore(code) + return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, destinationBefore)(code) : destinationBefore(code); } function destinationBefore(code) { - return factoryDestination( - effects, - destinationAfter, - nok, - 'definitionDestination', - 'definitionDestinationLiteral', - 'definitionDestinationLiteralMarker', - 'definitionDestinationRaw', - 'definitionDestinationString' - )(code) + return factoryDestination(effects, destinationAfter, + nok, "definitionDestination", "definitionDestinationLiteral", "definitionDestinationLiteralMarker", "definitionDestinationRaw", "definitionDestinationString")(code); } function destinationAfter(code) { - return effects.attempt(titleBefore, after, after)(code) + return effects.attempt(titleBefore, after, after)(code); } function after(code) { - return markdownSpace(code) - ? factorySpace(effects, afterWhitespace, 'whitespace')(code) - : afterWhitespace(code) + return markdownSpace(code) ? factorySpace(effects, afterWhitespace, "whitespace")(code) : afterWhitespace(code); } function afterWhitespace(code) { if (code === null || markdownLineEnding(code)) { - effects.exit('definition'); + effects.exit("definition"); self.parser.defined.push(identifier); - return ok(code) + return ok(code); } - return nok(code) + return nok(code); } } function tokenizeTitleBefore(effects, ok, nok) { - return titleBefore + return titleBefore; function titleBefore(code) { - return markdownLineEndingOrSpace(code) - ? factoryWhitespace(effects, beforeMarker)(code) - : nok(code) + return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, beforeMarker)(code) : nok(code); } function beforeMarker(code) { - return factoryTitle( - effects, - titleAfter, - nok, - 'definitionTitle', - 'definitionTitleMarker', - 'definitionTitleString' - )(code) + return factoryTitle(effects, titleAfter, nok, "definitionTitle", "definitionTitleMarker", "definitionTitleString")(code); } function titleAfter(code) { - return markdownSpace(code) - ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) - : titleAfterOptionalWhitespace(code) + return markdownSpace(code) ? factorySpace(effects, titleAfterOptionalWhitespace, "whitespace")(code) : titleAfterOptionalWhitespace(code); } function titleAfterOptionalWhitespace(code) { - return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + return code === null || markdownLineEnding(code) ? ok(code) : nok(code); } } @@ -4923,18 +4771,18 @@ const hardBreakEscape = { tokenize: tokenizeHardBreakEscape }; function tokenizeHardBreakEscape(effects, ok, nok) { - return start + return start; function start(code) { - effects.enter('hardBreakEscape'); + effects.enter("hardBreakEscape"); effects.consume(code); - return after + return after; } function after(code) { if (markdownLineEnding(code)) { - effects.exit('hardBreakEscape'); - return ok(code) + effects.exit("hardBreakEscape"); + return ok(code); } - return nok(code) + return nok(code); } } @@ -4948,96 +4796,83 @@ function resolveHeadingAtx(events, context) { let contentStart = 3; let content; let text; - if (events[contentStart][1].type === 'whitespace') { + if (events[contentStart][1].type === "whitespace") { contentStart += 2; } - if ( - contentEnd - 2 > contentStart && - events[contentEnd][1].type === 'whitespace' - ) { + if (contentEnd - 2 > contentStart && events[contentEnd][1].type === "whitespace") { contentEnd -= 2; } - if ( - events[contentEnd][1].type === 'atxHeadingSequence' && - (contentStart === contentEnd - 1 || - (contentEnd - 4 > contentStart && - events[contentEnd - 2][1].type === 'whitespace')) - ) { + if (events[contentEnd][1].type === "atxHeadingSequence" && (contentStart === contentEnd - 1 || contentEnd - 4 > contentStart && events[contentEnd - 2][1].type === "whitespace")) { contentEnd -= contentStart + 1 === contentEnd ? 2 : 4; } if (contentEnd > contentStart) { content = { - type: 'atxHeadingText', + type: "atxHeadingText", start: events[contentStart][1].start, end: events[contentEnd][1].end }; text = { - type: 'chunkText', + type: "chunkText", start: events[contentStart][1].start, end: events[contentEnd][1].end, - contentType: 'text' + contentType: "text" }; - splice(events, contentStart, contentEnd - contentStart + 1, [ - ['enter', content, context], - ['enter', text, context], - ['exit', text, context], - ['exit', content, context] - ]); + splice(events, contentStart, contentEnd - contentStart + 1, [['enter', content, context], ['enter', text, context], ['exit', text, context], ['exit', content, context]]); } - return events + return events; } function tokenizeHeadingAtx(effects, ok, nok) { let size = 0; - return start + return start; function start(code) { - effects.enter('atxHeading'); - return before(code) + effects.enter("atxHeading"); + return before(code); } function before(code) { - effects.enter('atxHeadingSequence'); - return sequenceOpen(code) + effects.enter("atxHeadingSequence"); + return sequenceOpen(code); } function sequenceOpen(code) { if (code === 35 && size++ < 6) { effects.consume(code); - return sequenceOpen + return sequenceOpen; } if (code === null || markdownLineEndingOrSpace(code)) { - effects.exit('atxHeadingSequence'); - return atBreak(code) + effects.exit("atxHeadingSequence"); + return atBreak(code); } - return nok(code) + return nok(code); } function atBreak(code) { if (code === 35) { - effects.enter('atxHeadingSequence'); - return sequenceFurther(code) + effects.enter("atxHeadingSequence"); + return sequenceFurther(code); } if (code === null || markdownLineEnding(code)) { - effects.exit('atxHeading'); - return ok(code) + effects.exit("atxHeading"); + return ok(code); } if (markdownSpace(code)) { - return factorySpace(effects, atBreak, 'whitespace')(code) + return factorySpace(effects, atBreak, "whitespace")(code); } - effects.enter('atxHeadingText'); - return data(code) + effects.enter("atxHeadingText"); + return data(code); } function sequenceFurther(code) { if (code === 35) { effects.consume(code); - return sequenceFurther + return sequenceFurther; } - effects.exit('atxHeadingSequence'); - return atBreak(code) + effects.exit("atxHeadingSequence"); + return atBreak(code); } function data(code) { if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { - effects.exit('atxHeadingText'); - return atBreak(code) + effects.exit("atxHeadingText"); + return atBreak(code); } effects.consume(code); - return data + return data; } } @@ -5124,16 +4959,16 @@ const nonLazyContinuationStart = { function resolveToHtmlFlow(events) { let index = events.length; while (index--) { - if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { - break + if (events[index][0] === 'enter' && events[index][1].type === "htmlFlow") { + break; } } - if (index > 1 && events[index - 2][1].type === 'linePrefix') { + if (index > 1 && events[index - 2][1].type === "linePrefix") { events[index][1].start = events[index - 2][1].start; events[index + 1][1].start = events[index - 2][1].start; events.splice(index - 2, 2); } - return events + return events; } function tokenizeHtmlFlow(effects, ok, nok) { const self = this; @@ -5142,385 +4977,346 @@ function tokenizeHtmlFlow(effects, ok, nok) { let buffer; let index; let markerB; - return start + return start; function start(code) { - return before(code) + return before(code); } function before(code) { - effects.enter('htmlFlow'); - effects.enter('htmlFlowData'); + effects.enter("htmlFlow"); + effects.enter("htmlFlowData"); effects.consume(code); - return open + return open; } function open(code) { if (code === 33) { effects.consume(code); - return declarationOpen + return declarationOpen; } if (code === 47) { effects.consume(code); closingTag = true; - return tagCloseStart + return tagCloseStart; } if (code === 63) { effects.consume(code); marker = 3; - return self.interrupt ? ok : continuationDeclarationInside + return self.interrupt ? ok : continuationDeclarationInside; } if (asciiAlpha(code)) { effects.consume(code); buffer = String.fromCharCode(code); - return tagName + return tagName; } - return nok(code) + return nok(code); } function declarationOpen(code) { if (code === 45) { effects.consume(code); marker = 2; - return commentOpenInside + return commentOpenInside; } if (code === 91) { effects.consume(code); marker = 5; index = 0; - return cdataOpenInside + return cdataOpenInside; } if (asciiAlpha(code)) { effects.consume(code); marker = 4; - return self.interrupt ? ok : continuationDeclarationInside + return self.interrupt ? ok : continuationDeclarationInside; } - return nok(code) + return nok(code); } function commentOpenInside(code) { if (code === 45) { effects.consume(code); - return self.interrupt ? ok : continuationDeclarationInside + return self.interrupt ? ok : continuationDeclarationInside; } - return nok(code) + return nok(code); } function cdataOpenInside(code) { - const value = 'CDATA['; + const value = "CDATA["; if (code === value.charCodeAt(index++)) { effects.consume(code); if (index === value.length) { - return self.interrupt ? ok : continuation + return self.interrupt ? ok : continuation; } - return cdataOpenInside + return cdataOpenInside; } - return nok(code) + return nok(code); } function tagCloseStart(code) { if (asciiAlpha(code)) { effects.consume(code); buffer = String.fromCharCode(code); - return tagName + return tagName; } - return nok(code) + return nok(code); } function tagName(code) { - if ( - code === null || - code === 47 || - code === 62 || - markdownLineEndingOrSpace(code) - ) { + if (code === null || code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { const slash = code === 47; const name = buffer.toLowerCase(); if (!slash && !closingTag && htmlRawNames.includes(name)) { marker = 1; - return self.interrupt ? ok(code) : continuation(code) + return self.interrupt ? ok(code) : continuation(code); } if (htmlBlockNames.includes(buffer.toLowerCase())) { marker = 6; if (slash) { effects.consume(code); - return basicSelfClosing + return basicSelfClosing; } - return self.interrupt ? ok(code) : continuation(code) + return self.interrupt ? ok(code) : continuation(code); } marker = 7; - return self.interrupt && !self.parser.lazy[self.now().line] - ? nok(code) - : closingTag - ? completeClosingTagAfter(code) - : completeAttributeNameBefore(code) + return self.interrupt && !self.parser.lazy[self.now().line] ? nok(code) : closingTag ? completeClosingTagAfter(code) : completeAttributeNameBefore(code); } if (code === 45 || asciiAlphanumeric(code)) { effects.consume(code); buffer += String.fromCharCode(code); - return tagName + return tagName; } - return nok(code) + return nok(code); } function basicSelfClosing(code) { if (code === 62) { effects.consume(code); - return self.interrupt ? ok : continuation + return self.interrupt ? ok : continuation; } - return nok(code) + return nok(code); } function completeClosingTagAfter(code) { if (markdownSpace(code)) { effects.consume(code); - return completeClosingTagAfter + return completeClosingTagAfter; } - return completeEnd(code) + return completeEnd(code); } function completeAttributeNameBefore(code) { if (code === 47) { effects.consume(code); - return completeEnd + return completeEnd; } if (code === 58 || code === 95 || asciiAlpha(code)) { effects.consume(code); - return completeAttributeName + return completeAttributeName; } if (markdownSpace(code)) { effects.consume(code); - return completeAttributeNameBefore + return completeAttributeNameBefore; } - return completeEnd(code) + return completeEnd(code); } function completeAttributeName(code) { - if ( - code === 45 || - code === 46 || - code === 58 || - code === 95 || - asciiAlphanumeric(code) - ) { + if (code === 45 || code === 46 || code === 58 || code === 95 || asciiAlphanumeric(code)) { effects.consume(code); - return completeAttributeName + return completeAttributeName; } - return completeAttributeNameAfter(code) + return completeAttributeNameAfter(code); } function completeAttributeNameAfter(code) { if (code === 61) { effects.consume(code); - return completeAttributeValueBefore + return completeAttributeValueBefore; } if (markdownSpace(code)) { effects.consume(code); - return completeAttributeNameAfter + return completeAttributeNameAfter; } - return completeAttributeNameBefore(code) + return completeAttributeNameBefore(code); } function completeAttributeValueBefore(code) { - if ( - code === null || - code === 60 || - code === 61 || - code === 62 || - code === 96 - ) { - return nok(code) + if (code === null || code === 60 || code === 61 || code === 62 || code === 96) { + return nok(code); } if (code === 34 || code === 39) { effects.consume(code); markerB = code; - return completeAttributeValueQuoted + return completeAttributeValueQuoted; } if (markdownSpace(code)) { effects.consume(code); - return completeAttributeValueBefore + return completeAttributeValueBefore; } - return completeAttributeValueUnquoted(code) + return completeAttributeValueUnquoted(code); } function completeAttributeValueQuoted(code) { if (code === markerB) { effects.consume(code); markerB = null; - return completeAttributeValueQuotedAfter + return completeAttributeValueQuotedAfter; } if (code === null || markdownLineEnding(code)) { - return nok(code) + return nok(code); } effects.consume(code); - return completeAttributeValueQuoted + return completeAttributeValueQuoted; } function completeAttributeValueUnquoted(code) { - if ( - code === null || - code === 34 || - code === 39 || - code === 47 || - code === 60 || - code === 61 || - code === 62 || - code === 96 || - markdownLineEndingOrSpace(code) - ) { - return completeAttributeNameAfter(code) + if (code === null || code === 34 || code === 39 || code === 47 || code === 60 || code === 61 || code === 62 || code === 96 || markdownLineEndingOrSpace(code)) { + return completeAttributeNameAfter(code); } effects.consume(code); - return completeAttributeValueUnquoted + return completeAttributeValueUnquoted; } function completeAttributeValueQuotedAfter(code) { if (code === 47 || code === 62 || markdownSpace(code)) { - return completeAttributeNameBefore(code) + return completeAttributeNameBefore(code); } - return nok(code) + return nok(code); } function completeEnd(code) { if (code === 62) { effects.consume(code); - return completeAfter + return completeAfter; } - return nok(code) + return nok(code); } function completeAfter(code) { if (code === null || markdownLineEnding(code)) { - return continuation(code) + return continuation(code); } if (markdownSpace(code)) { effects.consume(code); - return completeAfter + return completeAfter; } - return nok(code) + return nok(code); } function continuation(code) { if (code === 45 && marker === 2) { effects.consume(code); - return continuationCommentInside + return continuationCommentInside; } if (code === 60 && marker === 1) { effects.consume(code); - return continuationRawTagOpen + return continuationRawTagOpen; } if (code === 62 && marker === 4) { effects.consume(code); - return continuationClose + return continuationClose; } if (code === 63 && marker === 3) { effects.consume(code); - return continuationDeclarationInside + return continuationDeclarationInside; } if (code === 93 && marker === 5) { effects.consume(code); - return continuationCdataInside + return continuationCdataInside; } if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { - effects.exit('htmlFlowData'); - return effects.check( - blankLineBefore, - continuationAfter, - continuationStart - )(code) + effects.exit("htmlFlowData"); + return effects.check(blankLineBefore, continuationAfter, continuationStart)(code); } if (code === null || markdownLineEnding(code)) { - effects.exit('htmlFlowData'); - return continuationStart(code) + effects.exit("htmlFlowData"); + return continuationStart(code); } effects.consume(code); - return continuation + return continuation; } function continuationStart(code) { - return effects.check( - nonLazyContinuationStart, - continuationStartNonLazy, - continuationAfter - )(code) + return effects.check(nonLazyContinuationStart, continuationStartNonLazy, continuationAfter)(code); } function continuationStartNonLazy(code) { - effects.enter('lineEnding'); + effects.enter("lineEnding"); effects.consume(code); - effects.exit('lineEnding'); - return continuationBefore + effects.exit("lineEnding"); + return continuationBefore; } function continuationBefore(code) { if (code === null || markdownLineEnding(code)) { - return continuationStart(code) + return continuationStart(code); } - effects.enter('htmlFlowData'); - return continuation(code) + effects.enter("htmlFlowData"); + return continuation(code); } function continuationCommentInside(code) { if (code === 45) { effects.consume(code); - return continuationDeclarationInside + return continuationDeclarationInside; } - return continuation(code) + return continuation(code); } function continuationRawTagOpen(code) { if (code === 47) { effects.consume(code); buffer = ''; - return continuationRawEndTag + return continuationRawEndTag; } - return continuation(code) + return continuation(code); } function continuationRawEndTag(code) { if (code === 62) { const name = buffer.toLowerCase(); if (htmlRawNames.includes(name)) { effects.consume(code); - return continuationClose + return continuationClose; } - return continuation(code) + return continuation(code); } if (asciiAlpha(code) && buffer.length < 8) { effects.consume(code); buffer += String.fromCharCode(code); - return continuationRawEndTag + return continuationRawEndTag; } - return continuation(code) + return continuation(code); } function continuationCdataInside(code) { if (code === 93) { effects.consume(code); - return continuationDeclarationInside + return continuationDeclarationInside; } - return continuation(code) + return continuation(code); } function continuationDeclarationInside(code) { if (code === 62) { effects.consume(code); - return continuationClose + return continuationClose; } if (code === 45 && marker === 2) { effects.consume(code); - return continuationDeclarationInside + return continuationDeclarationInside; } - return continuation(code) + return continuation(code); } function continuationClose(code) { if (code === null || markdownLineEnding(code)) { - effects.exit('htmlFlowData'); - return continuationAfter(code) + effects.exit("htmlFlowData"); + return continuationAfter(code); } effects.consume(code); - return continuationClose + return continuationClose; } function continuationAfter(code) { - effects.exit('htmlFlow'); - return ok(code) + effects.exit("htmlFlow"); + return ok(code); } } function tokenizeNonLazyContinuationStart(effects, ok, nok) { const self = this; - return start + return start; function start(code) { if (markdownLineEnding(code)) { - effects.enter('lineEnding'); + effects.enter("lineEnding"); effects.consume(code); - effects.exit('lineEnding'); - return after + effects.exit("lineEnding"); + return after; } - return nok(code) + return nok(code); } function after(code) { - return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + return self.parser.lazy[self.now().line] ? nok(code) : ok(code); } } function tokenizeBlankLineBefore(effects, ok, nok) { - return start + return start; function start(code) { - effects.enter('lineEnding'); + effects.enter("lineEnding"); effects.consume(code); - effects.exit('lineEnding'); - return effects.attempt(blankLine, ok, nok) + effects.exit("lineEnding"); + return effects.attempt(blankLine, ok, nok); } } @@ -5533,331 +5329,299 @@ function tokenizeHtmlText(effects, ok, nok) { let marker; let index; let returnState; - return start + return start; function start(code) { - effects.enter('htmlText'); - effects.enter('htmlTextData'); + effects.enter("htmlText"); + effects.enter("htmlTextData"); effects.consume(code); - return open + return open; } function open(code) { if (code === 33) { effects.consume(code); - return declarationOpen + return declarationOpen; } if (code === 47) { effects.consume(code); - return tagCloseStart + return tagCloseStart; } if (code === 63) { effects.consume(code); - return instruction + return instruction; } if (asciiAlpha(code)) { effects.consume(code); - return tagOpen + return tagOpen; } - return nok(code) + return nok(code); } function declarationOpen(code) { if (code === 45) { effects.consume(code); - return commentOpenInside + return commentOpenInside; } if (code === 91) { effects.consume(code); index = 0; - return cdataOpenInside + return cdataOpenInside; } if (asciiAlpha(code)) { effects.consume(code); - return declaration + return declaration; } - return nok(code) + return nok(code); } function commentOpenInside(code) { if (code === 45) { effects.consume(code); - return commentEnd + return commentEnd; } - return nok(code) + return nok(code); } function comment(code) { if (code === null) { - return nok(code) + return nok(code); } if (code === 45) { effects.consume(code); - return commentClose + return commentClose; } if (markdownLineEnding(code)) { returnState = comment; - return lineEndingBefore(code) + return lineEndingBefore(code); } effects.consume(code); - return comment + return comment; } function commentClose(code) { if (code === 45) { effects.consume(code); - return commentEnd + return commentEnd; } - return comment(code) + return comment(code); } function commentEnd(code) { - return code === 62 - ? end(code) - : code === 45 - ? commentClose(code) - : comment(code) + return code === 62 ? end(code) : code === 45 ? commentClose(code) : comment(code); } function cdataOpenInside(code) { - const value = 'CDATA['; + const value = "CDATA["; if (code === value.charCodeAt(index++)) { effects.consume(code); - return index === value.length ? cdata : cdataOpenInside + return index === value.length ? cdata : cdataOpenInside; } - return nok(code) + return nok(code); } function cdata(code) { if (code === null) { - return nok(code) + return nok(code); } if (code === 93) { effects.consume(code); - return cdataClose + return cdataClose; } if (markdownLineEnding(code)) { returnState = cdata; - return lineEndingBefore(code) + return lineEndingBefore(code); } effects.consume(code); - return cdata + return cdata; } function cdataClose(code) { if (code === 93) { effects.consume(code); - return cdataEnd + return cdataEnd; } - return cdata(code) + return cdata(code); } function cdataEnd(code) { if (code === 62) { - return end(code) + return end(code); } if (code === 93) { effects.consume(code); - return cdataEnd + return cdataEnd; } - return cdata(code) + return cdata(code); } function declaration(code) { if (code === null || code === 62) { - return end(code) + return end(code); } if (markdownLineEnding(code)) { returnState = declaration; - return lineEndingBefore(code) + return lineEndingBefore(code); } effects.consume(code); - return declaration + return declaration; } function instruction(code) { if (code === null) { - return nok(code) + return nok(code); } if (code === 63) { effects.consume(code); - return instructionClose + return instructionClose; } if (markdownLineEnding(code)) { returnState = instruction; - return lineEndingBefore(code) + return lineEndingBefore(code); } effects.consume(code); - return instruction + return instruction; } function instructionClose(code) { - return code === 62 ? end(code) : instruction(code) + return code === 62 ? end(code) : instruction(code); } function tagCloseStart(code) { if (asciiAlpha(code)) { effects.consume(code); - return tagClose + return tagClose; } - return nok(code) + return nok(code); } function tagClose(code) { if (code === 45 || asciiAlphanumeric(code)) { effects.consume(code); - return tagClose + return tagClose; } - return tagCloseBetween(code) + return tagCloseBetween(code); } function tagCloseBetween(code) { if (markdownLineEnding(code)) { returnState = tagCloseBetween; - return lineEndingBefore(code) + return lineEndingBefore(code); } if (markdownSpace(code)) { effects.consume(code); - return tagCloseBetween + return tagCloseBetween; } - return end(code) + return end(code); } function tagOpen(code) { if (code === 45 || asciiAlphanumeric(code)) { effects.consume(code); - return tagOpen + return tagOpen; } if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { - return tagOpenBetween(code) + return tagOpenBetween(code); } - return nok(code) + return nok(code); } function tagOpenBetween(code) { if (code === 47) { effects.consume(code); - return end + return end; } if (code === 58 || code === 95 || asciiAlpha(code)) { effects.consume(code); - return tagOpenAttributeName + return tagOpenAttributeName; } if (markdownLineEnding(code)) { returnState = tagOpenBetween; - return lineEndingBefore(code) + return lineEndingBefore(code); } if (markdownSpace(code)) { effects.consume(code); - return tagOpenBetween + return tagOpenBetween; } - return end(code) + return end(code); } function tagOpenAttributeName(code) { - if ( - code === 45 || - code === 46 || - code === 58 || - code === 95 || - asciiAlphanumeric(code) - ) { + if (code === 45 || code === 46 || code === 58 || code === 95 || asciiAlphanumeric(code)) { effects.consume(code); - return tagOpenAttributeName + return tagOpenAttributeName; } - return tagOpenAttributeNameAfter(code) + return tagOpenAttributeNameAfter(code); } function tagOpenAttributeNameAfter(code) { if (code === 61) { effects.consume(code); - return tagOpenAttributeValueBefore + return tagOpenAttributeValueBefore; } if (markdownLineEnding(code)) { returnState = tagOpenAttributeNameAfter; - return lineEndingBefore(code) + return lineEndingBefore(code); } if (markdownSpace(code)) { effects.consume(code); - return tagOpenAttributeNameAfter + return tagOpenAttributeNameAfter; } - return tagOpenBetween(code) + return tagOpenBetween(code); } function tagOpenAttributeValueBefore(code) { - if ( - code === null || - code === 60 || - code === 61 || - code === 62 || - code === 96 - ) { - return nok(code) + if (code === null || code === 60 || code === 61 || code === 62 || code === 96) { + return nok(code); } if (code === 34 || code === 39) { effects.consume(code); marker = code; - return tagOpenAttributeValueQuoted + return tagOpenAttributeValueQuoted; } if (markdownLineEnding(code)) { returnState = tagOpenAttributeValueBefore; - return lineEndingBefore(code) + return lineEndingBefore(code); } if (markdownSpace(code)) { effects.consume(code); - return tagOpenAttributeValueBefore + return tagOpenAttributeValueBefore; } effects.consume(code); - return tagOpenAttributeValueUnquoted + return tagOpenAttributeValueUnquoted; } function tagOpenAttributeValueQuoted(code) { if (code === marker) { effects.consume(code); marker = undefined; - return tagOpenAttributeValueQuotedAfter + return tagOpenAttributeValueQuotedAfter; } if (code === null) { - return nok(code) + return nok(code); } if (markdownLineEnding(code)) { returnState = tagOpenAttributeValueQuoted; - return lineEndingBefore(code) + return lineEndingBefore(code); } effects.consume(code); - return tagOpenAttributeValueQuoted + return tagOpenAttributeValueQuoted; } function tagOpenAttributeValueUnquoted(code) { - if ( - code === null || - code === 34 || - code === 39 || - code === 60 || - code === 61 || - code === 96 - ) { - return nok(code) + if (code === null || code === 34 || code === 39 || code === 60 || code === 61 || code === 96) { + return nok(code); } if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { - return tagOpenBetween(code) + return tagOpenBetween(code); } effects.consume(code); - return tagOpenAttributeValueUnquoted + return tagOpenAttributeValueUnquoted; } function tagOpenAttributeValueQuotedAfter(code) { if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { - return tagOpenBetween(code) + return tagOpenBetween(code); } - return nok(code) + return nok(code); } function end(code) { if (code === 62) { effects.consume(code); - effects.exit('htmlTextData'); - effects.exit('htmlText'); - return ok + effects.exit("htmlTextData"); + effects.exit("htmlText"); + return ok; } - return nok(code) + return nok(code); } function lineEndingBefore(code) { - effects.exit('htmlTextData'); - effects.enter('lineEnding'); + effects.exit("htmlTextData"); + effects.enter("lineEnding"); effects.consume(code); - effects.exit('lineEnding'); - return lineEndingAfter + effects.exit("lineEnding"); + return lineEndingAfter; } function lineEndingAfter(code) { - return markdownSpace(code) - ? factorySpace( - effects, - lineEndingAfterPrefix, - 'linePrefix', - self.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 - )(code) - : lineEndingAfterPrefix(code) + return markdownSpace(code) ? factorySpace(effects, lineEndingAfterPrefix, "linePrefix", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4)(code) : lineEndingAfterPrefix(code); } function lineEndingAfterPrefix(code) { - effects.enter('htmlTextData'); - return returnState(code) + effects.enter("htmlTextData"); + return returnState(code); } } @@ -5880,17 +5644,13 @@ function resolveAllLabelEnd(events) { let index = -1; while (++index < events.length) { const token = events[index][1]; - if ( - token.type === 'labelImage' || - token.type === 'labelLink' || - token.type === 'labelEnd' - ) { - events.splice(index + 1, token.type === 'labelImage' ? 4 : 2); - token.type = 'data'; + if (token.type === "labelImage" || token.type === "labelLink" || token.type === "labelEnd") { + events.splice(index + 1, token.type === "labelImage" ? 4 : 2); + token.type = "data"; index++; } } - return events + return events; } function resolveToLabelEnd(events, context) { let index = events.length; @@ -5902,70 +5662,48 @@ function resolveToLabelEnd(events, context) { while (index--) { token = events[index][1]; if (open) { - if ( - token.type === 'link' || - (token.type === 'labelLink' && token._inactive) - ) { - break + if (token.type === "link" || token.type === "labelLink" && token._inactive) { + break; } - if (events[index][0] === 'enter' && token.type === 'labelLink') { + if (events[index][0] === 'enter' && token.type === "labelLink") { token._inactive = true; } } else if (close) { - if ( - events[index][0] === 'enter' && - (token.type === 'labelImage' || token.type === 'labelLink') && - !token._balanced - ) { + if (events[index][0] === 'enter' && (token.type === "labelImage" || token.type === "labelLink") && !token._balanced) { open = index; - if (token.type !== 'labelLink') { + if (token.type !== "labelLink") { offset = 2; - break + break; } } - } else if (token.type === 'labelEnd') { + } else if (token.type === "labelEnd") { close = index; } } const group = { - type: events[open][1].type === 'labelLink' ? 'link' : 'image', + type: events[open][1].type === "labelLink" ? "link" : "image", start: Object.assign({}, events[open][1].start), end: Object.assign({}, events[events.length - 1][1].end) }; const label = { - type: 'label', + type: "label", start: Object.assign({}, events[open][1].start), end: Object.assign({}, events[close][1].end) }; const text = { - type: 'labelText', + type: "labelText", start: Object.assign({}, events[open + offset + 2][1].end), end: Object.assign({}, events[close - 2][1].start) }; - media = [ - ['enter', group, context], - ['enter', label, context] - ]; + media = [['enter', group, context], ['enter', label, context]]; media = push(media, events.slice(open + 1, open + offset + 3)); media = push(media, [['enter', text, context]]); - media = push( - media, - resolveAll( - context.parser.constructs.insideSpan.null, - events.slice(open + offset + 4, close - 3), - context - ) - ); - media = push(media, [ - ['exit', text, context], - events[close - 2], - events[close - 1], - ['exit', label, context] - ]); + media = push(media, resolveAll(context.parser.constructs.insideSpan.null, events.slice(open + offset + 4, close - 3), context)); + media = push(media, [['exit', text, context], events[close - 2], events[close - 1], ['exit', label, context]]); media = push(media, events.slice(close + 1)); media = push(media, [['exit', group, context]]); splice(events, open, events.length, media); - return events + return events; } function tokenizeLabelEnd(effects, ok, nok) { const self = this; @@ -5973,182 +5711,125 @@ function tokenizeLabelEnd(effects, ok, nok) { let labelStart; let defined; while (index--) { - if ( - (self.events[index][1].type === 'labelImage' || - self.events[index][1].type === 'labelLink') && - !self.events[index][1]._balanced - ) { + if ((self.events[index][1].type === "labelImage" || self.events[index][1].type === "labelLink") && !self.events[index][1]._balanced) { labelStart = self.events[index][1]; - break + break; } } - return start + return start; function start(code) { if (!labelStart) { - return nok(code) + return nok(code); } if (labelStart._inactive) { - return labelEndNok(code) - } - defined = self.parser.defined.includes( - normalizeIdentifier( - self.sliceSerialize({ - start: labelStart.end, - end: self.now() - }) - ) - ); - effects.enter('labelEnd'); - effects.enter('labelMarker'); + return labelEndNok(code); + } + defined = self.parser.defined.includes(normalizeIdentifier(self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }))); + effects.enter("labelEnd"); + effects.enter("labelMarker"); effects.consume(code); - effects.exit('labelMarker'); - effects.exit('labelEnd'); - return after + effects.exit("labelMarker"); + effects.exit("labelEnd"); + return after; } function after(code) { if (code === 40) { - return effects.attempt( - resourceConstruct, - labelEndOk, - defined ? labelEndOk : labelEndNok - )(code) + return effects.attempt(resourceConstruct, labelEndOk, defined ? labelEndOk : labelEndNok)(code); } if (code === 91) { - return effects.attempt( - referenceFullConstruct, - labelEndOk, - defined ? referenceNotFull : labelEndNok - )(code) + return effects.attempt(referenceFullConstruct, labelEndOk, defined ? referenceNotFull : labelEndNok)(code); } - return defined ? labelEndOk(code) : labelEndNok(code) + return defined ? labelEndOk(code) : labelEndNok(code); } function referenceNotFull(code) { - return effects.attempt( - referenceCollapsedConstruct, - labelEndOk, - labelEndNok - )(code) + return effects.attempt(referenceCollapsedConstruct, labelEndOk, labelEndNok)(code); } function labelEndOk(code) { - return ok(code) + return ok(code); } function labelEndNok(code) { labelStart._balanced = true; - return nok(code) + return nok(code); } } function tokenizeResource(effects, ok, nok) { - return resourceStart + return resourceStart; function resourceStart(code) { - effects.enter('resource'); - effects.enter('resourceMarker'); + effects.enter("resource"); + effects.enter("resourceMarker"); effects.consume(code); - effects.exit('resourceMarker'); - return resourceBefore + effects.exit("resourceMarker"); + return resourceBefore; } function resourceBefore(code) { - return markdownLineEndingOrSpace(code) - ? factoryWhitespace(effects, resourceOpen)(code) - : resourceOpen(code) + return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, resourceOpen)(code) : resourceOpen(code); } function resourceOpen(code) { if (code === 41) { - return resourceEnd(code) - } - return factoryDestination( - effects, - resourceDestinationAfter, - resourceDestinationMissing, - 'resourceDestination', - 'resourceDestinationLiteral', - 'resourceDestinationLiteralMarker', - 'resourceDestinationRaw', - 'resourceDestinationString', - 32 - )(code) + return resourceEnd(code); + } + return factoryDestination(effects, resourceDestinationAfter, resourceDestinationMissing, "resourceDestination", "resourceDestinationLiteral", "resourceDestinationLiteralMarker", "resourceDestinationRaw", "resourceDestinationString", 32)(code); } function resourceDestinationAfter(code) { - return markdownLineEndingOrSpace(code) - ? factoryWhitespace(effects, resourceBetween)(code) - : resourceEnd(code) + return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, resourceBetween)(code) : resourceEnd(code); } function resourceDestinationMissing(code) { - return nok(code) + return nok(code); } function resourceBetween(code) { if (code === 34 || code === 39 || code === 40) { - return factoryTitle( - effects, - resourceTitleAfter, - nok, - 'resourceTitle', - 'resourceTitleMarker', - 'resourceTitleString' - )(code) + return factoryTitle(effects, resourceTitleAfter, nok, "resourceTitle", "resourceTitleMarker", "resourceTitleString")(code); } - return resourceEnd(code) + return resourceEnd(code); } function resourceTitleAfter(code) { - return markdownLineEndingOrSpace(code) - ? factoryWhitespace(effects, resourceEnd)(code) - : resourceEnd(code) + return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, resourceEnd)(code) : resourceEnd(code); } function resourceEnd(code) { if (code === 41) { - effects.enter('resourceMarker'); + effects.enter("resourceMarker"); effects.consume(code); - effects.exit('resourceMarker'); - effects.exit('resource'); - return ok + effects.exit("resourceMarker"); + effects.exit("resource"); + return ok; } - return nok(code) + return nok(code); } } function tokenizeReferenceFull(effects, ok, nok) { const self = this; - return referenceFull + return referenceFull; function referenceFull(code) { - return factoryLabel.call( - self, - effects, - referenceFullAfter, - referenceFullMissing, - 'reference', - 'referenceMarker', - 'referenceString' - )(code) + return factoryLabel.call(self, effects, referenceFullAfter, referenceFullMissing, "reference", "referenceMarker", "referenceString")(code); } function referenceFullAfter(code) { - return self.parser.defined.includes( - normalizeIdentifier( - self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) - ) - ) - ? ok(code) - : nok(code) + return self.parser.defined.includes(normalizeIdentifier(self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1))) ? ok(code) : nok(code); } function referenceFullMissing(code) { - return nok(code) + return nok(code); } } function tokenizeReferenceCollapsed(effects, ok, nok) { - return referenceCollapsedStart + return referenceCollapsedStart; function referenceCollapsedStart(code) { - effects.enter('reference'); - effects.enter('referenceMarker'); + effects.enter("reference"); + effects.enter("referenceMarker"); effects.consume(code); - effects.exit('referenceMarker'); - return referenceCollapsedOpen + effects.exit("referenceMarker"); + return referenceCollapsedOpen; } function referenceCollapsedOpen(code) { if (code === 93) { - effects.enter('referenceMarker'); + effects.enter("referenceMarker"); effects.consume(code); - effects.exit('referenceMarker'); - effects.exit('reference'); - return ok + effects.exit("referenceMarker"); + effects.exit("reference"); + return ok; } - return nok(code) + return nok(code); } } @@ -6159,28 +5840,26 @@ const labelStartImage = { }; function tokenizeLabelStartImage(effects, ok, nok) { const self = this; - return start + return start; function start(code) { - effects.enter('labelImage'); - effects.enter('labelImageMarker'); + effects.enter("labelImage"); + effects.enter("labelImageMarker"); effects.consume(code); - effects.exit('labelImageMarker'); - return open + effects.exit("labelImageMarker"); + return open; } function open(code) { if (code === 91) { - effects.enter('labelMarker'); + effects.enter("labelMarker"); effects.consume(code); - effects.exit('labelMarker'); - effects.exit('labelImage'); - return after + effects.exit("labelMarker"); + effects.exit("labelImage"); + return after; } - return nok(code) + return nok(code); } function after(code) { - return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs - ? nok(code) - : ok(code) + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs ? nok(code) : ok(code); } } @@ -6191,19 +5870,17 @@ const labelStartLink = { }; function tokenizeLabelStartLink(effects, ok, nok) { const self = this; - return start + return start; function start(code) { - effects.enter('labelLink'); - effects.enter('labelMarker'); + effects.enter("labelLink"); + effects.enter("labelMarker"); effects.consume(code); - effects.exit('labelMarker'); - effects.exit('labelLink'); - return after + effects.exit("labelMarker"); + effects.exit("labelLink"); + return after; } function after(code) { - return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs - ? nok(code) - : ok(code) + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs ? nok(code) : ok(code); } } @@ -6212,12 +5889,12 @@ const lineEnding = { tokenize: tokenizeLineEnding }; function tokenizeLineEnding(effects, ok) { - return start + return start; function start(code) { - effects.enter('lineEnding'); + effects.enter("lineEnding"); effects.consume(code); - effects.exit('lineEnding'); - return factorySpace(effects, ok, 'linePrefix') + effects.exit("lineEnding"); + return factorySpace(effects, ok, "linePrefix"); } } @@ -6228,36 +5905,34 @@ const thematicBreak$1 = { function tokenizeThematicBreak(effects, ok, nok) { let size = 0; let marker; - return start + return start; function start(code) { - effects.enter('thematicBreak'); - return before(code) + effects.enter("thematicBreak"); + return before(code); } function before(code) { marker = code; - return atBreak(code) + return atBreak(code); } function atBreak(code) { if (code === marker) { - effects.enter('thematicBreakSequence'); - return sequence(code) + effects.enter("thematicBreakSequence"); + return sequence(code); } if (size >= 3 && (code === null || markdownLineEnding(code))) { - effects.exit('thematicBreak'); - return ok(code) + effects.exit("thematicBreak"); + return ok(code); } - return nok(code) + return nok(code); } function sequence(code) { if (code === marker) { effects.consume(code); size++; - return sequence + return sequence; } - effects.exit('thematicBreakSequence'); - return markdownSpace(code) - ? factorySpace(effects, atBreak, 'whitespace')(code) - : atBreak(code) + effects.exit("thematicBreakSequence"); + return markdownSpace(code) ? factorySpace(effects, atBreak, "whitespace")(code) : atBreak(code); } } @@ -6280,148 +5955,98 @@ const indentConstruct = { function tokenizeListStart(effects, ok, nok) { const self = this; const tail = self.events[self.events.length - 1]; - let initialSize = - tail && tail[1].type === 'linePrefix' - ? tail[2].sliceSerialize(tail[1], true).length - : 0; + let initialSize = tail && tail[1].type === "linePrefix" ? tail[2].sliceSerialize(tail[1], true).length : 0; let size = 0; - return start + return start; function start(code) { - const kind = - self.containerState.type || - (code === 42 || code === 43 || code === 45 - ? 'listUnordered' - : 'listOrdered'); - if ( - kind === 'listUnordered' - ? !self.containerState.marker || code === self.containerState.marker - : asciiDigit(code) - ) { + const kind = self.containerState.type || (code === 42 || code === 43 || code === 45 ? "listUnordered" : "listOrdered"); + if (kind === "listUnordered" ? !self.containerState.marker || code === self.containerState.marker : asciiDigit(code)) { if (!self.containerState.type) { self.containerState.type = kind; effects.enter(kind, { _container: true }); } - if (kind === 'listUnordered') { - effects.enter('listItemPrefix'); - return code === 42 || code === 45 - ? effects.check(thematicBreak$1, nok, atMarker)(code) - : atMarker(code) + if (kind === "listUnordered") { + effects.enter("listItemPrefix"); + return code === 42 || code === 45 ? effects.check(thematicBreak$1, nok, atMarker)(code) : atMarker(code); } if (!self.interrupt || code === 49) { - effects.enter('listItemPrefix'); - effects.enter('listItemValue'); - return inside(code) + effects.enter("listItemPrefix"); + effects.enter("listItemValue"); + return inside(code); } } - return nok(code) + return nok(code); } function inside(code) { if (asciiDigit(code) && ++size < 10) { effects.consume(code); - return inside + return inside; } - if ( - (!self.interrupt || size < 2) && - (self.containerState.marker - ? code === self.containerState.marker - : code === 41 || code === 46) - ) { - effects.exit('listItemValue'); - return atMarker(code) + if ((!self.interrupt || size < 2) && (self.containerState.marker ? code === self.containerState.marker : code === 41 || code === 46)) { + effects.exit("listItemValue"); + return atMarker(code); } - return nok(code) + return nok(code); } function atMarker(code) { - effects.enter('listItemMarker'); + effects.enter("listItemMarker"); effects.consume(code); - effects.exit('listItemMarker'); + effects.exit("listItemMarker"); self.containerState.marker = self.containerState.marker || code; - return effects.check( - blankLine, - self.interrupt ? nok : onBlank, - effects.attempt( - listItemPrefixWhitespaceConstruct, - endOfPrefix, - otherPrefix - ) - ) + return effects.check(blankLine, + self.interrupt ? nok : onBlank, effects.attempt(listItemPrefixWhitespaceConstruct, endOfPrefix, otherPrefix)); } function onBlank(code) { self.containerState.initialBlankLine = true; initialSize++; - return endOfPrefix(code) + return endOfPrefix(code); } function otherPrefix(code) { if (markdownSpace(code)) { - effects.enter('listItemPrefixWhitespace'); + effects.enter("listItemPrefixWhitespace"); effects.consume(code); - effects.exit('listItemPrefixWhitespace'); - return endOfPrefix + effects.exit("listItemPrefixWhitespace"); + return endOfPrefix; } - return nok(code) + return nok(code); } function endOfPrefix(code) { - self.containerState.size = - initialSize + - self.sliceSerialize(effects.exit('listItemPrefix'), true).length; - return ok(code) + self.containerState.size = initialSize + self.sliceSerialize(effects.exit("listItemPrefix"), true).length; + return ok(code); } } function tokenizeListContinuation(effects, ok, nok) { const self = this; self.containerState._closeFlow = undefined; - return effects.check(blankLine, onBlank, notBlank) + return effects.check(blankLine, onBlank, notBlank); function onBlank(code) { - self.containerState.furtherBlankLines = - self.containerState.furtherBlankLines || - self.containerState.initialBlankLine; - return factorySpace( - effects, - ok, - 'listItemIndent', - self.containerState.size + 1 - )(code) + self.containerState.furtherBlankLines = self.containerState.furtherBlankLines || self.containerState.initialBlankLine; + return factorySpace(effects, ok, "listItemIndent", self.containerState.size + 1)(code); } function notBlank(code) { if (self.containerState.furtherBlankLines || !markdownSpace(code)) { self.containerState.furtherBlankLines = undefined; self.containerState.initialBlankLine = undefined; - return notInCurrentItem(code) + return notInCurrentItem(code); } self.containerState.furtherBlankLines = undefined; self.containerState.initialBlankLine = undefined; - return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code); } function notInCurrentItem(code) { self.containerState._closeFlow = true; self.interrupt = undefined; - return factorySpace( - effects, - effects.attempt(list$2, ok, nok), - 'linePrefix', - self.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 - )(code) + return factorySpace(effects, effects.attempt(list$2, ok, nok), "linePrefix", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4)(code); } } function tokenizeIndent$1(effects, ok, nok) { const self = this; - return factorySpace( - effects, - afterPrefix, - 'listItemIndent', - self.containerState.size + 1 - ) + return factorySpace(effects, afterPrefix, "listItemIndent", self.containerState.size + 1); function afterPrefix(code) { const tail = self.events[self.events.length - 1]; - return tail && - tail[1].type === 'listItemIndent' && - tail[2].sliceSerialize(tail[1], true).length === self.containerState.size - ? ok(code) - : nok(code) + return tail && tail[1].type === "listItemIndent" && tail[2].sliceSerialize(tail[1], true).length === self.containerState.size ? ok(code) : nok(code); } } function tokenizeListEnd(effects) { @@ -6429,21 +6054,10 @@ function tokenizeListEnd(effects) { } function tokenizeListItemPrefixWhitespace(effects, ok, nok) { const self = this; - return factorySpace( - effects, - afterPrefix, - 'listItemPrefixWhitespace', - self.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 + 1 - ) + return factorySpace(effects, afterPrefix, "listItemPrefixWhitespace", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + 1); function afterPrefix(code) { const tail = self.events[self.events.length - 1]; - return !markdownSpace(code) && - tail && - tail[1].type === 'listItemPrefixWhitespace' - ? ok(code) - : nok(code) + return !markdownSpace(code) && tail && tail[1].type === "listItemPrefixWhitespace" ? ok(code) : nok(code); } } @@ -6459,29 +6073,29 @@ function resolveToSetextUnderline(events, context) { let definition; while (index--) { if (events[index][0] === 'enter') { - if (events[index][1].type === 'content') { + if (events[index][1].type === "content") { content = index; - break + break; } - if (events[index][1].type === 'paragraph') { + if (events[index][1].type === "paragraph") { text = index; } } else { - if (events[index][1].type === 'content') { + if (events[index][1].type === "content") { events.splice(index, 1); } - if (!definition && events[index][1].type === 'definition') { + if (!definition && events[index][1].type === "definition") { definition = index; } } } const heading = { - type: 'setextHeading', + type: "setextHeading", start: Object.assign({}, events[text][1].start), end: Object.assign({}, events[events.length - 1][1].end) }; - events[text][1].type = 'setextHeadingText'; + events[text][1].type = "setextHeadingText"; if (definition) { events.splice(text, 0, ['enter', heading, context]); events.splice(definition + 1, 0, ['exit', events[content][1], context]); @@ -6490,52 +6104,46 @@ function resolveToSetextUnderline(events, context) { events[content][1] = heading; } events.push(['exit', heading, context]); - return events + return events; } function tokenizeSetextUnderline(effects, ok, nok) { const self = this; let marker; - return start + return start; function start(code) { let index = self.events.length; let paragraph; while (index--) { - if ( - self.events[index][1].type !== 'lineEnding' && - self.events[index][1].type !== 'linePrefix' && - self.events[index][1].type !== 'content' - ) { - paragraph = self.events[index][1].type === 'paragraph'; - break + if (self.events[index][1].type !== "lineEnding" && self.events[index][1].type !== "linePrefix" && self.events[index][1].type !== "content") { + paragraph = self.events[index][1].type === "paragraph"; + break; } } if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { - effects.enter('setextHeadingLine'); + effects.enter("setextHeadingLine"); marker = code; - return before(code) + return before(code); } - return nok(code) + return nok(code); } function before(code) { - effects.enter('setextHeadingLineSequence'); - return inside(code) + effects.enter("setextHeadingLineSequence"); + return inside(code); } function inside(code) { if (code === marker) { effects.consume(code); - return inside + return inside; } - effects.exit('setextHeadingLineSequence'); - return markdownSpace(code) - ? factorySpace(effects, after, 'lineSuffix')(code) - : after(code) + effects.exit("setextHeadingLineSequence"); + return markdownSpace(code) ? factorySpace(effects, after, "lineSuffix")(code) : after(code); } function after(code) { if (code === null || markdownLineEnding(code)) { - effects.exit('setextHeadingLine'); - return ok(code) + effects.exit("setextHeadingLine"); + return ok(code); } - return nok(code) + return nok(code); } } @@ -12406,7 +12014,6 @@ const remarkLintFinalNewline = lintRule$1( } } ); -var remarkLintFinalNewline$1 = remarkLintFinalNewline; const pointEnd = point('end'); const pointStart = point('start'); @@ -12537,7 +12144,6 @@ const remarkLintHardBreakSpaces = lintRule$1( }); } ); -var remarkLintHardBreakSpaces$1 = remarkLintHardBreakSpaces; function commonjsRequire(path) { throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); @@ -12978,7 +12584,6 @@ const remarkLintListItemBulletIndent = lintRule$1( } } ); -var remarkLintListItemBulletIndent$1 = remarkLintListItemBulletIndent; /** * remark-lint rule to warn when the whitespace after list item markers violate @@ -13370,7 +12975,6 @@ const remarkLintListItemIndent = lintRule$1( }); } ); -var remarkLintListItemIndent$1 = remarkLintListItemIndent; /** * remark-lint rule to warn for lazy lines in block quotes. @@ -13552,7 +13156,6 @@ const remarkLintNoBlockquoteWithoutMarker = lintRule$1( }); } ); -var remarkLintNoBlockquoteWithoutMarker$1 = remarkLintNoBlockquoteWithoutMarker; /** * remark-lint rule to warn when identifiers are defined multiple times. @@ -13671,7 +13274,6 @@ const remarkLintNoDuplicateDefinitions = lintRule$1( }); } ); -var remarkLintNoDuplicateDefinitions$1 = remarkLintNoDuplicateDefinitions; /** * remark-lint rule to warn when extra whitespace is used between hashes and @@ -13860,7 +13462,6 @@ const remarkLintNoHeadingContentIndent = lintRule$1( }); } ); -var remarkLintNoHeadingContentIndent$1 = remarkLintNoHeadingContentIndent; /** * remark-lint rule to warn when GFM autolink literals are used. @@ -13972,7 +13573,6 @@ const remarkLintNoLiteralUrls = lintRule$1( }); } ); -var remarkLintNoLiteralUrls$1 = remarkLintNoLiteralUrls; /** * remark-lint rule to warn when shortcut reference images are used. @@ -14049,7 +13649,6 @@ const remarkLintNoShortcutReferenceImage = lintRule$1( }); } ); -var remarkLintNoShortcutReferenceImage$1 = remarkLintNoShortcutReferenceImage; /** * remark-lint rule to warn when shortcut reference links are used. @@ -14126,7 +13725,6 @@ const remarkLintNoShortcutReferenceLink = lintRule$1( }); } ); -var remarkLintNoShortcutReferenceLink$1 = remarkLintNoShortcutReferenceLink; const js = /\s+/g; const html = /[\t\n\v\f\r ]+/g; @@ -14502,7 +14100,6 @@ const remarkLintNoUndefinedReferences = lintRule$1( } } ); -var remarkLintNoUndefinedReferences$1 = remarkLintNoUndefinedReferences; /** * remark-lint rule to warn when unreferenced definitions are used. @@ -14627,7 +14224,6 @@ const remarkLintNoUnusedDefinitions = lintRule$1( } } ); -var remarkLintNoUnusedDefinitions$1 = remarkLintNoUnusedDefinitions; /** * remark-lint rule to warn when ordered list markers are inconsistent. @@ -14806,27 +14402,25 @@ const remarkLintOrderedListMarkerStyle = lintRule$1( }); } ); -var remarkLintOrderedListMarkerStyle$1 = remarkLintOrderedListMarkerStyle; const remarkPresetLintRecommended = { plugins: [ remarkLint, - remarkLintFinalNewline$1, - remarkLintListItemBulletIndent$1, - [remarkLintListItemIndent$1, 'one'], - remarkLintNoBlockquoteWithoutMarker$1, - remarkLintNoLiteralUrls$1, - [remarkLintOrderedListMarkerStyle$1, '.'], - remarkLintHardBreakSpaces$1, - remarkLintNoDuplicateDefinitions$1, - remarkLintNoHeadingContentIndent$1, - remarkLintNoShortcutReferenceImage$1, - remarkLintNoShortcutReferenceLink$1, - remarkLintNoUndefinedReferences$1, - remarkLintNoUnusedDefinitions$1 + remarkLintFinalNewline, + remarkLintListItemBulletIndent, + [remarkLintListItemIndent, 'one'], + remarkLintNoBlockquoteWithoutMarker, + remarkLintNoLiteralUrls, + [remarkLintOrderedListMarkerStyle, '.'], + remarkLintHardBreakSpaces, + remarkLintNoDuplicateDefinitions, + remarkLintNoHeadingContentIndent, + remarkLintNoShortcutReferenceImage, + remarkLintNoShortcutReferenceLink, + remarkLintNoUndefinedReferences, + remarkLintNoUnusedDefinitions ] }; -var remarkPresetLintRecommended$1 = remarkPresetLintRecommended; /** * remark-lint rule to warn when block quotes are indented too much or @@ -14996,7 +14590,6 @@ const remarkLintBlockquoteIndentation = lintRule$1( }); } ); -var remarkLintBlockquoteIndentation$1 = remarkLintBlockquoteIndentation; /** * remark-lint rule to warn when list item checkboxes violate a given @@ -15231,7 +14824,6 @@ const remarkLintCheckboxCharacterStyle = lintRule$1( }); } ); -var remarkLintCheckboxCharacterStyle$1 = remarkLintCheckboxCharacterStyle; /** * remark-lint rule to warn when GFM tasklist checkboxes are followed by @@ -15379,7 +14971,6 @@ const remarkLintCheckboxContentIndent = lintRule$1( }); } ); -var remarkLintCheckboxContentIndent$1 = remarkLintCheckboxContentIndent; /** * remark-lint rule to warn when code blocks violate a given style. @@ -15597,7 +15188,6 @@ const remarkLintCodeBlockStyle = lintRule$1( }); } ); -var remarkLintCodeBlockStyle$1 = remarkLintCodeBlockStyle; /** * remark-lint rule to warn when consecutive whitespace is used in @@ -15709,13 +15299,12 @@ const remarkLintDefinitionSpacing = lintRule$1( }); } ); -var remarkLintDefinitionSpacing$1 = remarkLintDefinitionSpacing; const quotation = ( function (value, open, close) { - const start = open || '"'; - const end = close || start; + const start = open ; + const end = start; let index = -1; if (Array.isArray(value)) { const list = (value); @@ -15945,7 +15534,6 @@ const remarkLintFencedCodeFlag = lintRule$1( }); } ); -var remarkLintFencedCodeFlag$1 = remarkLintFencedCodeFlag; /** * remark-lint rule to warn when fenced code markers are @@ -16140,7 +15728,6 @@ const remarkLintFencedCodeMarker = lintRule$1( }); } ); -var remarkLintFencedCodeMarker$1 = remarkLintFencedCodeMarker; /** * remark-lint rule to warn for unexpected file extensions. @@ -16282,7 +15869,6 @@ const remarkLintFileExtension = lintRule$1( } } ); -var remarkLintFileExtension$1 = remarkLintFileExtension; /** * remark-lint rule to warn when definitions are used *in* the @@ -16453,7 +16039,6 @@ const remarkLintFinalDefinition = lintRule$1( } } ); -var remarkLintFinalDefinition$1 = remarkLintFinalDefinition; /** * remark-lint rule to warn when the first heading has an unexpected rank. @@ -16622,7 +16207,6 @@ const remarkLintFirstHeadingLevel = lintRule$1( }); } ); -var remarkLintFirstHeadingLevel$1 = remarkLintFirstHeadingLevel; function headingStyle(node, relative) { const last = node.children[node.children.length - 1]; @@ -16844,7 +16428,6 @@ const remarkLintHeadingStyle = lintRule$1( }); } ); -var remarkLintHeadingStyle$1 = remarkLintHeadingStyle; function displayStyle(style) { return style === 'atx' ? 'ATX' @@ -17138,7 +16721,6 @@ const remarkLintMaximumLineLength = lintRule$1( } } ); -var remarkLintMaximumLineLength$1 = remarkLintMaximumLineLength; /** * remark-lint rule to warn when multiple blank lines are used. @@ -17458,7 +17040,6 @@ const remarkLintNoConsecutiveBlankLines = lintRule$1( }); } ); -var remarkLintNoConsecutiveBlankLines$1 = remarkLintNoConsecutiveBlankLines; /** * remark-lint rule to warn when file names start with `a`, `the`, and such. @@ -17525,7 +17106,6 @@ const remarkLintNoFileNameArticles = lintRule$1( } } ); -var remarkLintNoFileNameArticles$1 = remarkLintNoFileNameArticles; /** * remark-lint rule to warn when file names contain consecutive dashes. @@ -17579,7 +17159,6 @@ const remarkLintNoFileNameConsecutiveDashes = lintRule$1( } } ); -var remarkLintNoFileNameConsecutiveDashes$1 = remarkLintNoFileNameConsecutiveDashes; /** * remark-lint rule to warn when file names start or end with dashes. @@ -17640,7 +17219,6 @@ const remarkLintNofileNameOuterDashes = lintRule$1( } } ); -var remarkLintNofileNameOuterDashes$1 = remarkLintNofileNameOuterDashes; /** * remark-lint rule to warn when headings are indented. @@ -17770,7 +17348,6 @@ const remarkLintNoHeadingIndent = lintRule$1( }); } ); -var remarkLintNoHeadingIndent$1 = remarkLintNoHeadingIndent; /** * remark-lint rule to warn when top-level headings are used multiple times. @@ -17944,7 +17521,6 @@ const remarkLintNoMultipleToplevelHeadings = lintRule$1( }); } ); -var remarkLintNoMultipleToplevelHeadings$1 = remarkLintNoMultipleToplevelHeadings; /** * remark-lint rule to warn when every line in shell code is preceded by `$`s. @@ -18094,7 +17670,6 @@ const remarkLintNoShellDollars = lintRule$1( }); } ); -var remarkLintNoShellDollars$1 = remarkLintNoShellDollars; /** * remark-lint rule to warn when GFM tables are indented. @@ -18272,7 +17847,6 @@ const remarkLintNoTableIndentation = lintRule$1( }); } ); -var remarkLintNoTableIndentation$1 = remarkLintNoTableIndentation; /** * remark-lint rule to warn when tabs are used. @@ -18388,7 +17962,6 @@ const remarkLintNoTabs = lintRule$1( } } ); -var remarkLintNoTabs$1 = remarkLintNoTabs; var sliced$1 = function (args, slice, sliceEnd) { var ret = []; @@ -22255,8 +21828,8 @@ const remarkLintNodejsYamlComments = lintRule$1( ); function lintRule(meta, rule) { - const id = typeof meta === 'string' ? meta : meta.origin; - const url = typeof meta === 'string' ? undefined : meta.url; + const id = meta ; + const url = undefined ; const parts = id.split(':'); const source = parts[1] ? parts[0] : undefined; const ruleId = parts[1]; @@ -22556,7 +22129,6 @@ const remarkLintRuleStyle = lintRule$1( }); } ); -var remarkLintRuleStyle$1 = remarkLintRuleStyle; /** * remark-lint rule to warn when strong markers are inconsistent. @@ -22735,7 +22307,6 @@ const remarkLintStrongMarker = lintRule$1( }); } ); -var remarkLintStrongMarker$1 = remarkLintStrongMarker; /** * remark-lint rule to warn when GFM table cells are padded inconsistently. @@ -23413,7 +22984,6 @@ const remarkLintTableCellPadding = lintRule$1( } } ); -var remarkLintTableCellPadding$1 = remarkLintTableCellPadding; /** * remark-lint rule to warn when GFM table rows have no initial or @@ -23634,7 +23204,6 @@ const remarkLintTablePipes = lintRule$1( } } ); -var remarkLintTablePipes$1 = remarkLintTablePipes; /** * remark-lint rule to warn when unordered list markers are inconsistent. @@ -23814,18 +23383,17 @@ const remarkLintUnorderedListMarkerStyle = lintRule$1( }); } ); -var remarkLintUnorderedListMarkerStyle$1 = remarkLintUnorderedListMarkerStyle; const plugins = [ remarkGfm, - remarkPresetLintRecommended$1, - [remarkLintBlockquoteIndentation$1, 2], - [remarkLintCheckboxCharacterStyle$1, { checked: "x", unchecked: " " }], - remarkLintCheckboxContentIndent$1, - [remarkLintCodeBlockStyle$1, "fenced"], - remarkLintDefinitionSpacing$1, + remarkPresetLintRecommended, + [remarkLintBlockquoteIndentation, 2], + [remarkLintCheckboxCharacterStyle, { checked: "x", unchecked: " " }], + remarkLintCheckboxContentIndent, + [remarkLintCodeBlockStyle, "fenced"], + remarkLintDefinitionSpacing, [ - remarkLintFencedCodeFlag$1, + remarkLintFencedCodeFlag, { flags: [ "bash", @@ -23847,21 +23415,21 @@ const plugins = [ ], }, ], - [remarkLintFencedCodeMarker$1, "`"], - [remarkLintFileExtension$1, "md"], - remarkLintFinalDefinition$1, - [remarkLintFirstHeadingLevel$1, 1], - [remarkLintHeadingStyle$1, "atx"], - [remarkLintMaximumLineLength$1, 120], - remarkLintNoConsecutiveBlankLines$1, - remarkLintNoFileNameArticles$1, - remarkLintNoFileNameConsecutiveDashes$1, - remarkLintNofileNameOuterDashes$1, - remarkLintNoHeadingIndent$1, - remarkLintNoMultipleToplevelHeadings$1, - remarkLintNoShellDollars$1, - remarkLintNoTableIndentation$1, - remarkLintNoTabs$1, + [remarkLintFencedCodeMarker, "`"], + [remarkLintFileExtension, "md"], + remarkLintFinalDefinition, + [remarkLintFirstHeadingLevel, 1], + [remarkLintHeadingStyle, "atx"], + [remarkLintMaximumLineLength, 120], + remarkLintNoConsecutiveBlankLines, + remarkLintNoFileNameArticles, + remarkLintNoFileNameConsecutiveDashes, + remarkLintNofileNameOuterDashes, + remarkLintNoHeadingIndent, + remarkLintNoMultipleToplevelHeadings, + remarkLintNoShellDollars, + remarkLintNoTableIndentation, + remarkLintNoTabs, remarkLintNoTrailingSpaces$1, remarkLintNodejsLinks, remarkLintNodejsYamlComments, @@ -23886,11 +23454,11 @@ const plugins = [ { yes: "V8" }, ], ], - remarkLintRuleStyle$1, - [remarkLintStrongMarker$1, "*"], - [remarkLintTableCellPadding$1, "padded"], - remarkLintTablePipes$1, - [remarkLintUnorderedListMarkerStyle$1, "*"], + remarkLintRuleStyle, + [remarkLintStrongMarker, "*"], + [remarkLintTableCellPadding, "padded"], + remarkLintTablePipes, + [remarkLintUnorderedListMarkerStyle, "*"], ]; const settings = { emphasis: "_", @@ -23900,17 +23468,9 @@ const remarkPresetLintNode = { plugins, settings }; function read(description, options, callback) { const file = toVFile(description); - if (!callback && typeof options === 'function') { - callback = options; - options = undefined; - } - if (!callback) { + { return new Promise(executor) } - executor(resolve, callback); - function resolve(result) { - callback(undefined, result); - } function executor(resolve, reject) { let fp; try { @@ -24535,7 +24095,7 @@ function reporter(files, options) { 'Unexpected value for `files`, expected one or more `VFile`s' ) } - const settings = options || {}; + const settings = {}; const colorEnabled = typeof settings.color === 'boolean' ? settings.color : color; let oneFileMode = false; diff --git a/tools/lint-md/package-lock.json b/tools/lint-md/package-lock.json index c04c92f75ead2e..fb2f863261f205 100644 --- a/tools/lint-md/package-lock.json +++ b/tools/lint-md/package-lock.json @@ -18,7 +18,7 @@ "devDependencies": { "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", - "rollup": "^4.15.0", + "rollup": "^4.17.0", "rollup-plugin-cleanup": "^3.2.1" } }, @@ -101,9 +101,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.15.0.tgz", - "integrity": "sha512-O63bJ7p909pRRQfOJ0k/Jp8gNFMud+ZzLLG5EBWquylHxmRT2k18M2ifg8WyjCgFVdpA7+rI0YZ8EkAtg6dSUw==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.0.tgz", + "integrity": "sha512-nNvLvC2fjC+3+bHYN9uaGF3gcyy7RHGZhtl8TB/kINj9hiOQza8kWJGZh47GRPMrqeseO8U+Z8ElDMCZlWBdHA==", "cpu": [ "arm" ], @@ -114,9 +114,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.15.0.tgz", - "integrity": "sha512-5UywPdmC9jiVOShjQx4uuIcnTQOf85iA4jgg8bkFoH5NYWFfAfrJpv5eeokmTdSmYwUTT5IrcrBCJNkowhrZDA==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.0.tgz", + "integrity": "sha512-+kjt6dvxnyTIAo7oHeYseYhDyZ7xRKTNl/FoQI96PHkJVxoChldJnne/LzYqpqidoK1/0kX0/q+5rrYqjpth6w==", "cpu": [ "arm64" ], @@ -127,9 +127,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.15.0.tgz", - "integrity": "sha512-hNkt75uFfWpRxHItCBmbS0ba70WnibJh6yz60WShSWITLlVRbkvAu1E/c7RlliPY4ajhqJd0UPZz//gNalTd4g==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.0.tgz", + "integrity": "sha512-Oj6Tp0unMpGTBjvNwbSRv3DopMNLu+mjBzhKTt2zLbDJ/45fB1pltr/rqrO4bE95LzuYwhYn127pop+x/pzf5w==", "cpu": [ "arm64" ], @@ -140,9 +140,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.15.0.tgz", - "integrity": "sha512-HnC5bTP7qdfO9nUw/mBhNcjOEZfbS8NwV+nFegiMhYOn1ATAGZF4kfAxR9BuZevBrebWCxMmxm8NCU1CUoz+wQ==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.0.tgz", + "integrity": "sha512-3nJx0T+yptxMd+v93rBRxSPTAVCv8szu/fGZDJiKX7kvRe9sENj2ggXjCH/KK1xZEmJOhaNo0c9sGMgGdfkvEw==", "cpu": [ "x64" ], @@ -153,9 +153,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.15.0.tgz", - "integrity": "sha512-QGOIQIJZeIIqMsc4BUGe8TnV4dkXhSW2EhaQ1G4LqMUNpkyeLztvlDlOoNHn7SR7a4dBANdcEbPkkEzz3rzjzA==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.0.tgz", + "integrity": "sha512-Vb2e8p9b2lxxgqyOlBHmp6hJMu/HSU6g//6Tbr7x5V1DlPCHWLOm37nSIVK314f+IHzORyAQSqL7+9tELxX3zQ==", "cpu": [ "arm" ], @@ -166,9 +166,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.15.0.tgz", - "integrity": "sha512-PS/Cp8CinYgoysQ8i4UXYH/TZl06fXszvY/RDkyBYgUB1+tKyOMS925/4FZhfrhkl3XQEKjMc3BKtsxpB9Tz9Q==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.0.tgz", + "integrity": "sha512-Md60KsmC5ZIaRq/bYYDloklgU+XLEZwS2EXXVcSpiUw+13/ZASvSWQ/P92rQ9YDCL6EIoXxuQ829JkReqdYbGg==", "cpu": [ "arm" ], @@ -179,9 +179,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.15.0.tgz", - "integrity": "sha512-XzOsnD6lGDP+k+vGgTYAryVGu8N89qpjMN5BVFUj75dGVFP3FzIVAufJAraxirpDwEQZA7Gjs0Vo5p4UmnnjsA==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.0.tgz", + "integrity": "sha512-zL5rBFtJ+2EGnMRm2TqKjdjgFqlotSU+ZJEN37nV+fiD3I6Gy0dUh3jBWN0wSlcXVDEJYW7YBe+/2j0N9unb2w==", "cpu": [ "arm64" ], @@ -192,9 +192,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.15.0.tgz", - "integrity": "sha512-+ScJA4Epbx/ZQGjDnbvTAcb8ZD06b+TlIka2UkujbKf1I/A+yrvEcJwG3/27zMmvcWMQyeCJhbL9TlSjzL0B7Q==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.0.tgz", + "integrity": "sha512-s2xAyNkJqUdtRVgNK4NK4P9QttS538JuX/kfVQOdZDI5FIKVAUVdLW7qhGfmaySJ1EvN/Bnj9oPm5go9u8navg==", "cpu": [ "arm64" ], @@ -205,9 +205,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.15.0.tgz", - "integrity": "sha512-1cUSvYgnyTakM4FDyf/GxUCDcqmj/hUh1NOizEOJU7+D5xEfFGCxgcNOs3hYBeRMUCcGmGkt01EhD3ILgKpGHQ==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.0.tgz", + "integrity": "sha512-7F99yzVT67B7IUNMjLD9QCFDCyHkyCJMS1dywZrGgVFJao4VJ9szrIEgH67cR+bXQgEaY01ur/WSL6B0jtcLyA==", "cpu": [ "ppc64" ], @@ -218,9 +218,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.15.0.tgz", - "integrity": "sha512-3A1FbHDbBUvpJXFAZwVsiROIcstVHP9AX/cwnyIhAp+xyQ1cBCxywKtuzmw0Av1MDNNg/y/9dDHtNypfRa8bdw==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.0.tgz", + "integrity": "sha512-leFtyiXisfa3Sg9pgZJwRKITWnrQfhtqDjCamnZhkZuIsk1FXmYwKoTkp6lsCgimIcneFFkHKp/yGLxDesga4g==", "cpu": [ "riscv64" ], @@ -231,9 +231,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.15.0.tgz", - "integrity": "sha512-hYPbhg9ow6/mXIkojc8LOeiip2sCTuw1taWyoOXTOWk9vawIXz8x7B4KkgWUAtvAElssxhSyEXr2EZycH/FGzQ==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.0.tgz", + "integrity": "sha512-FtOgui6qMJ4jbSXTxElsy/60LEe/3U0rXkkz2G5CJ9rbHPAvjMvI+3qF0A0fwLQ5hW+/ZC6PbnS2KfRW9JkgDQ==", "cpu": [ "s390x" ], @@ -244,9 +244,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.15.0.tgz", - "integrity": "sha512-511qln5mPSUKwv7HI28S1jCD1FK+2WbX5THM9A9annr3c1kzmfnf8Oe3ZakubEjob3IV6OPnNNcesfy+adIrmw==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.0.tgz", + "integrity": "sha512-v6eiam/1w3HUfU/ZjzIDodencqgrSqzlNuNtiwH7PFJHYSo1ezL0/UIzmS2lpSJF1ORNaplXeKHYmmdt81vV2g==", "cpu": [ "x64" ], @@ -257,9 +257,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.15.0.tgz", - "integrity": "sha512-4qKKGTDIv2bQZ+afhPWqPL+94+dLtk4lw1iwbcylKlLNqQ/Yyjof2CFYBxf6npiDzPV+zf4EWRiHb26/4Vsm9w==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.0.tgz", + "integrity": "sha512-OUhkSdpM5ofVlVU2k4CwVubYwiwu1a4jYWPpubzN7Vzao73GoPBowHcCfaRSFRz1SszJ3HIsk3dZYk4kzbqjgw==", "cpu": [ "x64" ], @@ -270,9 +270,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.15.0.tgz", - "integrity": "sha512-nEtaFBHp1OnbOf+tz66DtID579sNRHGgMC23to8HUyVuOCpCMD0CvRNqiDGLErLNnwApWIUtUl1VvuovCWUxwg==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.0.tgz", + "integrity": "sha512-uL7UYO/MNJPGL/yflybI+HI+n6+4vlfZmQZOCb4I+z/zy1wisHT3exh7oNQsnL6Eso0EUTEfgQ/PaGzzXf6XyQ==", "cpu": [ "arm64" ], @@ -283,9 +283,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.15.0.tgz", - "integrity": "sha512-5O49NykwSgX6iT2HgZ6cAoGHt6T/FqNMB5OqFOGxU/y1GyFSHquox1sK2OqApQc0ANxiHFQEMNDLNVCL7AUDnQ==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.0.tgz", + "integrity": "sha512-4WnSgaUiUmXILwFqREdOcqvSj6GD/7FrvSjhaDjmwakX9w4Z2F8JwiSP1AZZbuRkPqzi444UI5FPv33VKOWYFQ==", "cpu": [ "ia32" ], @@ -296,9 +296,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.15.0.tgz", - "integrity": "sha512-YA0hTwCunmKNeTOFWdJuKhdXse9jBqgo34FDo+9aS0spfCkp+wj0o1bCcOOTu+0P48O95GTfkLTAaVonwNuIdQ==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.0.tgz", + "integrity": "sha512-ve+D8t1prRSRnF2S3pyDtTXDlvW1Pngbz76tjgYFQW1jxVSysmQCZfPoDAo4WP+Ano8zeYp85LsArZBI12HfwQ==", "cpu": [ "x64" ], @@ -1165,9 +1165,9 @@ } }, "node_modules/micromark-core-commonmark": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", - "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", + "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", "funding": [ { "type": "GitHub Sponsors", @@ -2675,9 +2675,9 @@ } }, "node_modules/rollup": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.15.0.tgz", - "integrity": "sha512-i0ir57IMF5o7YvNYyUNeIGG+IZaaucnGZAOsSctO2tPLXlCEaZzyBa+QhpHNSgtpyLMoDev2DyN6a7J1dQA8Tw==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.0.tgz", + "integrity": "sha512-wZJSn0WMtWrxhYKQRt5Z6GIXlziOoMDFmbHmRfL3v+sBTAshx2DBq1AfMArB7eIjF63r4ocn2ZTAyUptg/7kmQ==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -2690,22 +2690,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.15.0", - "@rollup/rollup-android-arm64": "4.15.0", - "@rollup/rollup-darwin-arm64": "4.15.0", - "@rollup/rollup-darwin-x64": "4.15.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.15.0", - "@rollup/rollup-linux-arm-musleabihf": "4.15.0", - "@rollup/rollup-linux-arm64-gnu": "4.15.0", - "@rollup/rollup-linux-arm64-musl": "4.15.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.15.0", - "@rollup/rollup-linux-riscv64-gnu": "4.15.0", - "@rollup/rollup-linux-s390x-gnu": "4.15.0", - "@rollup/rollup-linux-x64-gnu": "4.15.0", - "@rollup/rollup-linux-x64-musl": "4.15.0", - "@rollup/rollup-win32-arm64-msvc": "4.15.0", - "@rollup/rollup-win32-ia32-msvc": "4.15.0", - "@rollup/rollup-win32-x64-msvc": "4.15.0", + "@rollup/rollup-android-arm-eabi": "4.17.0", + "@rollup/rollup-android-arm64": "4.17.0", + "@rollup/rollup-darwin-arm64": "4.17.0", + "@rollup/rollup-darwin-x64": "4.17.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.17.0", + "@rollup/rollup-linux-arm-musleabihf": "4.17.0", + "@rollup/rollup-linux-arm64-gnu": "4.17.0", + "@rollup/rollup-linux-arm64-musl": "4.17.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.17.0", + "@rollup/rollup-linux-riscv64-gnu": "4.17.0", + "@rollup/rollup-linux-s390x-gnu": "4.17.0", + "@rollup/rollup-linux-x64-gnu": "4.17.0", + "@rollup/rollup-linux-x64-musl": "4.17.0", + "@rollup/rollup-win32-arm64-msvc": "4.17.0", + "@rollup/rollup-win32-ia32-msvc": "4.17.0", + "@rollup/rollup-win32-x64-msvc": "4.17.0", "fsevents": "~2.3.2" } }, diff --git a/tools/lint-md/package.json b/tools/lint-md/package.json index bdb781b420fb60..a94880091fe484 100644 --- a/tools/lint-md/package.json +++ b/tools/lint-md/package.json @@ -16,7 +16,7 @@ "devDependencies": { "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-node-resolve": "^15.2.3", - "rollup": "^4.15.0", + "rollup": "^4.17.0", "rollup-plugin-cleanup": "^3.2.1" } }